
これは、TCP ポートがどのように機能するかをより深く理解するための仮説的な質問です。
マシンに複数のイーサネット カードがあり、それらが異なるサブネットに接続されているとします。この場合、ローカル アドレス/ポートをバインドせずに TCP 経由でリモート マシンに接続したい場合、カーネルが IP アドレスとポートを決定します。
私の理解では、カーネルはインターフェイスのプライマリ IP に基づいて IP アドレスを選択し、インターフェイスはルーティング テーブルに従って選択されます。
TCP ポート部分については、カーネルが未使用の (一時的な) ポートを見つけます。問題は、カーネルが使用済みの TCP ポートを IP アドレスで保持するかどうかです。つまり、ポートa.b.c.d:12345
(インターフェイス A の IP と仮定) を使用していて、パケットがインターフェイス B から送信される場合、e.f.g.h:12345
(インターフェイス B の IP と仮定) を使用できますか?
どちらの方法にも議論の余地はあります。確立された TCP 接続はローカル/リモート IP/ポートの 4 組で識別されるため、答えはyes
「ポートを再び使用できる」12345
ということのようです。ただし、カーネルは TCP 層を準備するときにルーティング情報 (つまりインターフェイス、つまりソース IP) を認識しないため、IP 層に進む前にカーネルが TCP 層で IP 依存の空き TCP ポートを割り当てることは不可能です。
カーネル関数inet_csk_get_port
テーブルをスキャンしますhinfo->bhash
。このテーブルは、ハッシュ キーにポート番号のみを使用します。これは、エフェメラル ポートがグローバルに一意であることを意味します。これが本当であれば、複数のネットワーク カードを搭載したマシンでは、リソースの (少しの) 無駄のように思えます。ここで重要な事実を見逃しましたか? 誰かがこれを明確にするのを手伝ってくれることを願っています。ありがとうございます!