UDP を信頼できるものにするために Linux カーネル モジュールを開発するにはどうすればよいですか? これは私の大学の課題であり、どのように進めればよいかわかりません。新しいカーネル モジュールをロードして、Linux カーネルのデフォルトの UDP 動作を変更するにはどうすればよいですか? そのようなカーネルモジュールをどのようにプログラムするのですか?
15 に答える
信頼できる UDP は、単に TCP を使用することと同じではありません。いくつかの違いがありますが、最も顕著な違いは、UDP メッセージ全体を常に受信するか、まったく受信しないことが保証されていることです。一方、部分的な TCP メッセージを受信することは可能であるだけでなく、非常に一般的です。
これは単なる宿題なので、単一の送信メッセージを実装し、ACK を待ち、次のメッセージ ルーチンをタイムアウトで送信することをお勧めします。タイムアウトが発生した場合は、失敗を宣言する前にメッセージを何度か再送信します。はい、これは必要以上に遅くなります。スループットを改善するためのテクニックはたくさんありますが、あなたの課題では、それらを使う必要がない可能性が高いです。
かわいそうに「TCP だけを使う」ように言い続ける人は、信頼できる UDP 実装が TCP 経由で使用される正当な理由があることを無視しています - そしてそれはデータグラムのセマンティクスではありません (TCP の上に簡単にレイヤー化できます)。
主な正当な推進要因は、多くのノードとの間のコネクションレス通信であり、そうでなければ過度の接続多重度を必要とする可能性があります
これは、ブロードキャスト データフィード、クラスタ内システム ソフトウェア通信などによく使用されます。
UDPを信頼できるものにする方法を尋ねることは、質問に間違った方法でアプローチしている可能性があると思います. UDP は定義上多かれ少なかれ信頼性がありません - 当然のことです。プロトコルの OS 側の実装をより「信頼できる」ものにすることはできません。
UDP を使用する非常に多くのアプリケーションは、TCP の正確な信頼性よりも、低オーバーヘッド、低遅延の性質を必要とするため、UDP を使用しています。しかし、これらのアプリケーションのほとんどすべてには、特定の種類のメッセージのエンドツーエンドの受信を検証するための何らかのメカニズムが必要であり、おそらく再構築や初期ハンドシェイクも必要です。たとえば、VoIP テレフォニーの SIP について考えてみましょう。TCP の潜在的なスリーウェイ ハンドシェイクと非常に緩やかな輻輳制御は、適切なコール セットアップ時間または QoS には実際には受け入れられませんが、メッセージを確認する何らかの方法が必要であることは間違いありません (これが、SIP 用語での暫定応答の目的です)。または、オンライン ゲームで使用されているさまざまなプロトコル - 基本的な考え方は同じです。
割り当ての本当の意図は、明確に述べられていなくても、UDPを信頼できるものにすることではなく、 UDPを使用し、カプセル化された独自の通信スキーム内にプリミティブな信頼性の抽象化レイヤーを持つ単純なプログラムを作成することである可能性が非常に高いです。いわばUDPで。
ヘッドオブライン ブロッキングなどの TCP 信頼性機能の一部をオフにできるメッセージ ベースのトランスポート層プロトコルが絶対に必要な場合は、SCTPを調べてください。API には、基になる接続をマスクする「 UDP モード」もあります。
これはまだ進行中の作業であるため、ユーザーが使用できるとは期待できませんが、管理しているコンピューターにのみ必要な場合は問題ありません。FreeBSD はほとんどの開発作業が行われる場所ですが、さまざまなフレーバーの unixで実装されています。YMMV。
TCP が既に行っているように、UDP の上に TCP をオーバーレイします。「信頼できる UDP」は矛盾した表現です。そのように設計されていません。
Linuxカーネルを変更する方法の詳細が必要な場合、私の最初の応答はgoogle "linux kernel"であり、おそらくそれに"socket"を追加することです。LinuxカーネルのWebサイトには、他にもフォローできるリードがあるようです。
私の提案は
1)LinuxでUDPがどのように実装されている
かを見てください2)RUDPがどのように実装されているかを見てください(誰かがすでに述べたように)
3)...(ここで魔法を起こさせます)
4)利益!えーと…宿題が終わった!
新しいモジュールを介して既存の UDP コードの動作を変更する簡単な方法があるかどうかはわかりません。
より簡単なのは、UDP コード (net/ipv4/udp.c) を使用して、新しい IP プロトコル番号で新しいモジュールを作成し、このコードを変更して信頼できる UDP プロトコルを実装することです。名前が既存のシンボルと衝突しないように、すべての外部シンボルの名前を変更し、プロトコル番号 (17) が登録されている場所を見つけて変更し、Makefile を更新して新しいモジュールをビルドし、おそらくエントリを配置する必要があります。 Kconfig.
/etc/protocols を見て、既に割り当てられているプロトコル ID を確認してください。
編集: udp.c をモジュールとしてビルドできないようです。コードをモジュールにする方法を確認するには、他のプロトコル (ipip.c や ip_gre.c など) を調べる必要があります。
正直なところ、これはひっかけ問題なのだろうか。通信するには 2 つの当事者が必要であり、送信者がパケットを再送信することを望んでいることを送信者が認識 (または気に) していることを確認することはできません。UDP 自体がこれを実行できる場合、カーネルが既にサポートしていると強く思います。
残っているのは、新しいプロトコルを実装するモジュールを特定して実装することです。それは何も悪いことではありません.他の人がすでにあなたに提案をしています.UDP実装を使用して実際のパケットトランスポートを処理できると確信しています. ただし、これは新しいプロトコルの実装であり、新しい機能を実現するために UDP を少しひねっただけではないことを覚えておいてください。
信頼性の高いUDPが必要な場合は、SCTP(Stream Control Transmission Protocol)を使用するのが最善の選択です。これは現在、あらゆる場所で使用されている確立されたプロトコルです。
信頼できるとはどういう意味かを考える必要があります。また、パケットを順番に並べる必要があるかどうか、または順序が乱れても問題ないかどうかを判断する必要があります。順不同で問題ない場合は、ACK、再送信、およびタイムアウト スキームを考え出す必要があります。また、パケットの断片化を処理するかどうかを決定する必要があります。それを回避できる場合は、断片化を防ぐためにパケットのサイズを制限することをお勧めします。
おそらく、あなたが行き詰まっているのは「信頼できる」という概念です。技術用語で正確に何を意味するのか、明確な概念をお持ちですか? (または、より関連性が高いと思いますが、インストラクターがそれによって何を意味しているのか。)
プロトコルが信頼できると呼ぶために必要な特性について正確な考えを持っている場合、それは作業の方向性を提供する可能性があります。 -world の実装により、宿題の完了がより実現可能になる場合もあります。
何らかの理由で UDP を使用しなければならない場合 (真剣に、TCP を使用するだけです)、迅速で簡単な信頼性機能として、プレゼンス ハートビート、ack、および xor されたチェックサムがあります。