UDPポート6666を介して通信しようとしています(目標はnetconsole用のリスナーを設定することですが、ここでは関係ありません)。
聞く面では、nc -luv 6666
送る側で。nc -uv LISTENER_IP 6666
送受信でき、生活が良いです。
今、リスナーを実行状態にして発信者を終了し、別のリスナーを起動します。すぐに終了します。ネットワーク追跡によると、受信サーバーICMP ポートに接続できません。。しかし、リスナーは次の内容を聞き続けます。
$ sudo ss -nlup|grep 6666
UNCONN 0 0 :::6666 :::* users:(("nc",pid=3417,fd=3))
リスナーを終了し、新しいリスナーを実行します。送信者を殺すまで、すべてが以前と同じように機能します。
送信者と受信者は同じネットワーク上の物理システムです。実際のマシンとそのマシンで実行されている仮想マシン間の同じテストは、同じ結果を生成します。
この行動をどのように説明すべきでしょうか?
ベストアンサー1
これは、UDPの「接続」の仕組みによって予想される動作です。これは議論されるnc6(1)
マニュアルページからsocat
(「UDP」)ですが、以下にも適用されますnc
。
netcat6のUDPサポートは、接続モードと受信モードの両方でうまく機能します。受信モードでUDPを使用すると、netcat6はオプションのアドレスおよび/またはポート(指定されている場合)と一致するすべての送信元からUDPパケットを受け入れます。ただし、最初のパケットが受信されると、netcat6はそのクライアントから後続のパケットのみを受信します。これは、UDPソケットを「接続された」状態に設定することによって行われます(udp(4)とconnect(2)を参照)。他のソースからのパケットはカーネルによって廃棄され、ICMP 接続できない応答が送信されます。
UDPを使用してリモートホストに接続すると、nc6はリモートサーバーが受信しているかどうかに関係なく、接続が開いていることを報告します。これはUDPが接続されていないプロトコルなので、実際には接続を必要としないからです。ただし、最初のパケットを送信した後、サーバーはICMPに接続できない応答で応答でき、nc6は「接続が拒否されました」というエラーメッセージで終了します。
発信者から接続すると、任意のUDPソースポートが選択されます。その後、受信機はその特定のペアにバインドされ、そのhost:port
ポイントから他の接続を受信しません。この問題を解決するには、送信者が常に同じポートを使用するように強制する必要があります。この例を使用するsocat
理由は簡単です。
観客:
# socat -d -d UDP-LISTEN:6666 stdout
2018/01/29 22:02:02 socat[20969] N listening on UDP AF=2 0.0.0.0:6666
2018/01/29 22:02:07 socat[20969] N accepting UDP connection from AF=2 10.100.0.5:39000
2018/01/29 22:02:07 socat[20969] N using stdout for reading and writing
2018/01/29 22:02:07 socat[20969] N starting data transfer loop with FDs [5,5] and [1,1]
hello
bye
hello1
bye1
送信者:
# socat -d -d stdin UDP:listener-host:6666
2018/01/29 22:01:56 socat[8237] N using stdin for reading and writing
2018/01/29 22:01:56 socat[8237] N opening connection to AF=2 10.100.0.3:6666
2018/01/29 22:01:56 socat[8237] N successfully connected from local address AF=2 10.100.0.5:39000
2018/01/29 22:01:56 socat[8237] N starting data transfer loop with FDs [0,0] and [5,5]
hello
bye
2018/01/29 22:02:10 socat[8237] N socket 1 (fd 0) is at EOF
2018/01/29 22:02:10 socat[8237] N exiting with status 0
# socat -d -d stdin UDP:listener-host:6666
2018/01/29 22:02:13 socat[8238] N using stdin for reading and writing
2018/01/29 22:02:13 socat[8238] N opening connection to AF=2 10.100.0.3:6666
2018/01/29 22:02:13 socat[8238] N successfully connected from local address AF=2 10.100.0.5:57125
2018/01/29 22:02:13 socat[8238] N starting data transfer loop with FDs [0,0] and [5,5]
hello
2018/01/29 22:02:16 socat[8238] E read(5, 0x5619f9b09330, 8192): Connection refused
2018/01/29 22:02:16 socat[8238] N exit(1)
# socat -d -d stdin UDP:listener-host:6666,sourceport=39000
2018/01/29 22:05:17 socat[8280] N using stdin for reading and writing
2018/01/29 22:05:17 socat[8280] N opening connection to AF=2 10.100.0.3:6666
2018/01/29 22:05:17 socat[8280] N successfully connected from local address AF=2 10.100.0.5:39000
2018/01/29 22:05:17 socat[8280] N starting data transfer loop with FDs [0,0] and [5,5]
hello1
bye1
2018/01/29 22:05:23 socat[8280] N socket 1 (fd 0) is at EOF
2018/01/29 22:05:24 socat[8280] N exiting with status 0
ご覧のとおり、送信者の送信元ポートは変更されますが、強制的に同じポートを再利用すると機能します。