#53 Closing listening UDP socket on first packet causes drops

open
nobody
5
2014-12-17
2011-07-18
Ralph Corderoy
No

If "netcat -l -u -p 4242 127.0.0.1" is running and the sender, in this
case bash, sends two or more UDP packets in quick succession all but the
first is wilfully discarded by GNU netcat.

select(4, [3], NULL, NULL, NULL) = 1 (in [3])
recvmsg(3, {
msg_name(16)={
sa_family=AF_INET,
sin_port=htons(34047),
sin_addr=inet_addr("127.0.0.1")
},
msg_iov(1)=[{"foo\n"..., 1024}],
msg_controllen=32,
{
cmsg_len=28, cmsg_level=SOL_IP, cmsg_type=, ...
},
msg_flags=0
}, MSG_PEEK) = 4
close(3) = 0
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {
sa_family=AF_INET,
sin_port=htons(4242),
sin_addr=inet_addr("127.0.0.1")
}, 16) = 0
connect(3, {
sa_family=AF_INET,
sin_port=htons(34047),
sin_addr=inet_addr("127.0.0.1")
}, 16) = 0
write(1, "foo\n", 4) = 4

The problem is caused by GNU netcat closing the socket, discarding the
packets that are waiting to be read. It should instead connect(2) the
existing socket.

OpenBSD's netcat and socat do it this way and no packets are lost.

Discussion