Devido à maneira como as "conexões" UDP funcionam, esse é o comportamento esperado. Isso é discutido em a página nc6(1)
man ("UDP"), mas também é aplicável a socat
e nc
:
UDP support in netcat6 works very well in both connect and in listen mode. When using UDP in listen mode netcat6 accepts UDP packets from any source that matches the optional address and/or port specified (if it was specified). However, once the first packet is received, netcat6 will only receive packets from that client in future. This is done by putting the UDP socket into "connected" state (see udp(4) and connect(2)). Packets from other sources are discarded by the kernel and an ICMP unreachable response is sent.
When connecting to a remote host using UDP, nc6 will report that the connection is open regardless of whether a remote server is listening. This is because UDP is a connectionless protocol, and hence no connection establishment is actually required. However, after sending the first packet of data, a server may reply with an ICMP unreachable response causing nc6 to exit with a 'Connection refused' error message.
Quando você se conecta do lado do remetente, uma porta de origem UDP aleatória é escolhida. O receptor então se liga a esse par host:port
específico e não ouvirá nenhuma outra conexão a partir de então. Para resolver isso, você precisa forçar o remetente a sempre usar a mesma porta. Eu usei socat
para este exemplo porque era mais fácil de fazer:
Ouvinte:
# 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
Remetente:
# 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
Como você pode ver, a porta de origem mudou no remetente, mas se eu forcei a reutilização da mesma porta funcionou.