2016-06-24 12 views
0

私はUDPの上で動作するカスタムトランスポートプロトコルを実装しようとしています。私はこのプロトコルのヘッダーをUDPデータフィールドの始めに、ユーザースペースからのデータがskbuffにコピーされる直前に追加したいと思います。UDPがソケットに渡す直前にこのデータを処理したいのでヘッダーを作成し、カーネルで必要な処理を行います。だから、 UDPデータグラムデータフィールドの始めにカスタムデータを追加する(Linuxカーネルで)

  1. は、どのように私は私のヘッダが(struct new_headerを言う)udp_sendmsg()関数内のデータの先頭に追加されていることを確認します。私はこれをskbuffのデータフィールドにコピーして、ユーザー空間からの実際のデータをそれにコピーするか、遅くともUDPチェックサムがデータで計算される前にコピーする必要があると仮定します。これはコード内で正確にどこに起こりますか?
  2. 正確にudp_recvmsg()にある機能は、ソケットに渡されるデータですか?私はそれがskb_copy_datagram_iovec()だと思います。

答えて

1

どのように私は自分のヘッダが(構造体new_headerを言う)udp_sendmsg()関数内のデータの先頭に追加されていることを確認します。私はこの をskbuffのデータフィールドにコピーしてから、ユーザー空間の実際のデータ をコピーするか、遅くともUDP のチェックサムがデータで計算される前にコピーする必要があります。これはコード で正確にどこに起こりますか?

2あなたが考えることができますオプション:
あなた1.IfあなたがUDPソケットまたはエンキャップからデータグラムを受信した後、ユーザー空間であなたのプロトコルを実装し、あなただけのカーネル、およびプロトコルデキャップを行うために話をするUDPソケットを使用することができますUDPソケットにデータを送信する前に
2.プロトコルをカーネル空間に実装したい場合は、独自のソケットタイプを実装する必要があります。カーネルソースに既に存在するトンネルソケットコードを例(例:L2TP)で確認できます。ソケットタイプをカーネルに登録すると、ユーザスペースからカーネルスペースに送信されるソケットデータは、encapコード(udp_sendmsg()と同等のもの)で処理され、コードをエンコードするとudp_sendmsg()ネットワークスタック

正確には、udp_recvmsg()関数はソケットに渡されるデータですか?私はそれがskb_copy_datagram_iovec()だと思います。

あなたが見ているカーネルのバージョンが不明です。カーネル4.6では、skb_copy_datagram_msg() - > skb_copy_datagram_iter()です。これは、データグラムがbuffにコピーされてからuserspaceに戻る場所です。
実際に、udp_recvmsg()は、ユーザー空間がソケットからデータを受信しようとするときに呼び出されるため、udp_recvmsg()はすでにソケットコンテキスト内にあります。 ネットワークスタックは、データグラムをsk_receive_queueに入れてsock_queue_rcv_skb()のソケットにデータグラムを渡します。このようなカーネル4.6で

コールチェーン:

__udp4_lib_rcv --> 
    udp_queue_rcv_skb(sk, skb); --> sock_queue_rcv_skb() 

その後userpsaceはしてデータを取得する:

recv(); 
... ... 
-------system call --------- 
... ... 
udp_recvmsg --> 
__skb_recv_datagram --> 
__skb_try_recv_datagram --> (get the datagram from sk_receive_queue) 
+0

私は考え出し残り、私の疑問のほとんどを説明する精巧な答え、ありがとうコードを実行してコーディングが有効になっていてもシームレスに動作するので、データグラムの終わりにカスタムヘッダーを追加する方が簡単です(私はUDPのすべての機能を使用する予定です) –

関連する問題