web-dev-qa-db-ja.com

パケットはOSに到達しますが、プロセスには到達しません

私の問題をタイトルに要約するのが少し難しい場合は申し訳ありません。それは私が思いつくことができる最高です。

TL; DRバージョン:パケットがOSに到達したが、宛先プロセスには到達しない場合、どのようにデバッグしますか?

説明:2つのプロセスがあり、2つのデバイスで実行され、TCP/IPを介して通信しています。最初のデバイスは、イーサネットケーブルを介して直接2番目のデバイスにのみ接続されます。 2番目のデバイスはネットワークに接続されています。 2つのデバイスが接続され、問題なく通信を開始します。次に、最初のデバイスを物理的に切断し、しばらくしてからケーブルを再接続します。 Wiresharkを使用すると、デバイスがパケットを受信して​​いることがわかります。パケットの宛先ポート番号が正しいことがわかります。プロセスが正しいポート番号で[0.0.0.0:port]をリッスンしていることがわかります。しかし、何らかの理由で、プロセスはパケットを受信して​​いません。

しかし、これは奇妙なことです。これは、最初のデバイスが2番目のデバイスに直接接続されている場合にのみ発生します。両方のデバイスをスイッチに接続してこのテストを繰り返すと、ケーブルを再接続した後、問題なくパケットがプロセスに到達します。

どちらのシナリオでも、IPを静的に設定しています。そして、問題のプロセスは、ZMQスタックを使用してパケットを受信して​​います。私が最も混乱しているのは、ネットワークトポロジがLinuxオペレーティングシステム内で発生しているルーティングに影響を与える理由です(その場合)。

このシナリオをデバッグするにはどうすればよいですか?どこから始めればいいですか?問題がどこにあるかを絞り込むために実行できるテストはありますか?さらに明確にしてほしい場合はお知らせください。

P.S.両方のシステムでファイアウォールを無効にしています。

1
pooya13

これは多くの推測ですが、これまで実際のシステムで見た理由はいくつかあります:(私はほぼチェックサムだと思います。)

  • ファイアウォール(netfilter)。 nft list rulesetiptables-save -cを確認してください。
  • IPヘッダーまたはTCP/UDPパケットのいずれかのチェックサムが正しくありません。 (ハードウェアチェックサムオフロードは、VMで不思議なことに無視されたUDPパケットの原因であることが何度かあります。)受信側の統計についてはnetstat -sをチェックし、「InCsumErrors:」を探します。
  • 厳密rp_filter逆ルートは別のインターフェイスを指すため、パケットを破棄します。これを無効にするには、sysctl net.ipv4.conf.all.rp_filter=0を実行します。
  • 特定の{dstaddr:dstport}は、特定のIPアドレスにバインドされた別のリスニングソケットと一致します。これは、ワイルドカード{0.0.0.0:dstport}ソケットよりも優先されます。
  • {srcaddr:srcport→dstaddr:dstport}の特定の組み合わせは、connectedソケットと一致するため、リスニングソケットには配信されません。これはUDPにも当てはまります。ネットワーク上に接続はありませんが、特定のリモートエンドポイントに関連付けられた「接続された」UDPソケットを持つことができます。
  • (IPv6固有:)宛先システムでは、DAD(重複アドレス検出)障害のため、割り当てられたIPアドレスは非アクティブです。 ip -6 addrでは「dadfailed」と表示されます。
2
user1686

dropwatch を試して、カーネルが何らかの理由でパケットをドロップするかどうかを確認することもできます。

2
dirkt