6

私はVxWorksデバイスとLinuxマシン間のUDPソケット通信を含むプロジェクトに取り組んでいます。このプロジェクトでは、UDPヘッダーのチェックサムフィールドを利用したいと思います。

VxWorksソケットインターフェイスではchecksum、発信UDPパケットのフィールドがデフォルトで有効になっているようです。

ただし、通常のUnixソケットインターフェイスの場合、着信パケットのチェックサムをチェックして発信パケットのチェックサムを設定するUDPソケットを開くためのフラグやその他の方法はないようです。

通常のUnixソケットインターフェイスの場合、そのようなフラグは存在しますか?

ありがとう!

4

3 に答える 3

5

私は専門家ではありませんが、man 7 udpこの問題について言わなければならないことは、デフォルトで有効になっていることを示唆しています。

UDPはチェックサムを生成してチェックし、送信エラーをキャッチします。

それを無効にする方法については触れられていません。

編集:私は現在のカーネルソースを検索するのが面倒ですが、このページは、無効なチェックサムを持つパケットが単にドロップされることを示唆しています(csum_copy_err一部)。

于 2012-12-26T17:12:18.477 に答える
2

(私は専門家ではありません。以下は完全に間違っている可能性があります。)

ネットワークインターフェイス(またはドライバーまたは同等のもの)は、着信パケットのチェックサムをチェックする必要があります。all-bits-zeroのチェックサムは、「発信インターフェイスがチェックサムを生成しなかった」ことを意味します。インターフェイスは他のチェックサム(チェックサムフィールドで使用される1の補数エンコーディングのすべてのビット1、別名「負のゼロ」を含む)をチェックし、チェックに失敗した場合はパケットをドロップする必要があります。

したがって、着信パケットのUDPチェックサムチェックを無効にすることはできません(それらのパケットにチェックサムが提供されている場合、つまり)。これは、UDP標準の必須部分にすぎません。

受信インターフェイスは、チェックサムなしでパケットをドロップするか[1]、またはアプリケーションにパケットを渡すことができます(または、アプリケーションに目的の動作を構成させることができますが、これが可能な場合は、その方法がわかりません)。

制御できる可能性があるのは、送信インターフェイスが発信パケットのチェックサムを生成するかどうかだけです。プラットフォーム固有になります。以下にいくつかの方法をまとめましたが、機能する場合と機能しない場合があります。警告レクター。

プラットフォームのデフォルトの動作を採用すると、デフォルトでUDPチェックサムが生成されます—私はそれにお金をかけます。

[1] — RFC 8085:「アプリケーションはオプションでチェックサムがゼロのUDPデータグラムを破棄することが許可されています[ RFC1122 ]。」


1999年のこのcomp.protocols.tcp-ipの投稿はndd、Solarisで、コマンドラインを介して発信パケットでのUDPチェックサムの生成をグローバルに無効にできることを示しています。

ndd -set /dev/udp udp_do_checksum 0

このnddユーティリティはSolarisカーネルに固有であり、LinuxまたはFreeBSDには存在しません。また、Solarisドキュメントでさえ次のように述べています。

udp_do_checksum
  This parameter controls whether UDP calculates the checksum
  on outgoing UDP/IPv4 packets.

Default
  1 (enabled)

When to Change
  Do not change this parameter.

(LinuxとFreeBSDでは、/dev/udp「実際には存在しません」。これはBashによって提供されたフィクションです/dev/udp。Solarisで「実際に存在する」かどうかはわかりません。)


Microsoftのドキュメントによると、Windowsでは、文書化されたオプションを使用して、ソケットごとにプログラムでUDPチェックサムの生成を無効にできます。

DWORD trueValue = 1;
int rc = setsockopt(fd, IPPROTO_UDP, UDP_NOCHECKSUM, (const char*)&yes, sizeof yes);
if (rc != 0) { perror("setsockopt"); abort(); }

このスレッドは、FreeBSD(Mac OS Xなど)では、文書化されていない(ただし、2018年1月現在存在する)オプションを使用して、ソケットごとにプログラムでチェックサム生成を無効にできることを意味します。

int yes = 1;
int rc = setsockopt(sock, IPPROTO_UDP, UDP_NOCKSUM, (void*)&yes, sizeof yes);
if (rc != 0) { perror("setsockopt"); abort(); }

そして最後に、このスレッドは、Linuxで、他の方法で文書化されていない(ただし、2018年1月現在存在する)オプションを使用して、ソケットごとにプログラムでチェックサム生成を無効にできることを意味します。

int yes = 1;
int rc = setsockopt(sock, SOL_SOCKET, SO_NO_CHECK, (void*)&yes, sizeof yes);
if (rc != 0) { perror("setsockopt"); abort(); }

于 2018-01-02T22:02:35.390 に答える
1

@zneakによるコメントに関して、RFC6936では、トンネルトラフィックなどの制限された条件下で、IPv6を介したUDPゼロチェックサムの使用が許可されるようになりました。Linuxは、このためのUDP_NO_CHECK6_TXおよびUDP_NO_CHECK6_RXソケットオプションを定義しています。このコミットを参照してください。

于 2019-01-18T09:29:26.887 に答える