ip_recv_error (ip_sockglue.c) - why zero the port on ICMP errors?

From: Z
Date: Wed Dec 27 2006 - 01:13:12 EST

Hello all,
I am developing a UDP application and wish to receive
the ICMP unreachable messages that some hosts send in
response to a UDP datagram that hits a closed port. I
use the IP_RECVERR on my socket, recvmsg (fd, &msg,
MSG_ERRQUEUE) and all that, however the returned port
in the sock_extended_err SO_EE_OFFENDER data always 0.

The following code in net/ipv4/ip_sockglue.c
illustrates this:
sin = &errhdr.offender;
sin->sin_family = AF_UNSPEC;
if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP) {
struct inet_sock *inet = inet_sk(sk);

sin->sin_family = AF_INET;
sin->sin_addr.s_addr = skb->nh.iph->saddr;
sin->sin_port = 0;
memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
if (inet->cmsg_flags)
ip_cmsg_recv(msg, skb);
For some reason, even though the full IP header is
available here (and the port preserved in
ip_icmp_error), sin->sin_port is set to zero in the
ip_recv_error function, which really hurts the
potential use of this in some applications which need
the port to uniquely identify multiple clients using
the same IP address.

I realise there's more than one way to do this - as a
workaround, I am using the msg.msg_name field, however
on earlier kernel versions (or maybe an earlier libc -
I didn't track down the reason), the msg.msg_name
field is not set correctly and the data fetched by
SO_EE_OFFENDER is the only way to find out the full
source of the error.

I'm just curious as to the reasoning behind zeroing
out the port in this piece of code, it doesn't seem to
make much sense as usermode applications will just see
a zero port instead of the real port. I noticed in
earlier kernel versions that sin_port and sin_zero
were unspecified which led to uninitialized kernel
stack memory being returned, maybe this was a hasty
bug fix for that problem?

I hope someone can quell my curiosity behind this :). Thanks.

Send instant messages to your online friends http://uk.messenger.yahoo.com
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/