getsockname() returns wrong address of unbound socket

Olaf Titz (olaf@bigred.inka.de)
21 Feb 1997 15:53:46 +0100


This code in net/ipv4/af_inet.c, function inet_getname():

__u32 addr = sk->rcv_saddr;
if (!addr) {
addr = sk->saddr;
if (!addr)
addr = ip_my_addr();
}
sin->sin_port = sk->dummy_th.source;
sin->sin_addr.s_addr = addr;

has the following "surprise factor" result:

struct sockaddr_in sa;
int sal=sizeof(sa);
int s=socket(AF_INET, SOCK_DGRAM, 0);
getsockname(s, &sa, &sal);

will leave 127.0.0.1 instead of 0.0.0.0 in sa.sin_addr.

Any program that records this address and does a bind() to it later
will bind to the wrong address. E.g. libsocks5 does that, as the SOCKS
protocol requires that the client tells the server the local address
of its UDP sockets. (It also requires that the local address be
INADDR_ANY if it isn't known at the moment, which is consistent with
what one would expect from an unbound getsockname()).

So what happens with a socksified UDP program is that the socket will
be bound to 127.0.0.1 instead of INADDR_ANY and won't receive messages
from the SOCKS proxy.

Is there any reason why getsockname() does this ip_my_addr() thing at all?

olaf