bind() to INADDR_LOOPBACK

tricorn

Registered
Ok, how come I can't bind to INADDR_LOOPBACK under MacOSX (10.3.4)? If I try to connect to 127.0.0.1 to something listening to INADDR_ANY, the two sockets are IPv6, so I suspect that's part of it, but lo0 is enabled for IPv4 at 127.0.0.1.

This has always worked for me on other Unix systems, to do a TCP listen that can only be connected to from the local host. Is this a bug or a "feature"?
 
Are you sure you can't bind to INADDR_LOOPBACK? I just tried it with sin_family==AF_INET, sin_addr.s_addr==INADDR_LOOPBACK and sin_port==9876, and I could connect to 127.0.0.1 and receive data without any problems. Could you tell us more about what kind of errors you're getting?
 
Here's my code (without the includes and error checking). I realize htons() and htonl() on a PPC are no-ops, just including them for correctness and portability.

server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);;

bind(server, (struct sockaddr *) &addr, sizeof addr)

last call returns -1, with errno = EADDRNOTAVAIL

bind() works fine if I use INADDR_ANY. Just tried it with my actual IP address and that doesn't work either.

I'm running this on a G5 with 10.3.4 and latest developer tools. Code works fine on a Linux box (x86 does require the htonX() calls).

Also tried disabling IPv6, didn't change anything. Minor corrrection to original report: when I said connecting to localhost connected using IPv6, turns out that was ssh; just connecting to my socket when bound using INADDR_ANY does use IPv4 and 127.0.0.1 as expected.

There are other processes that are listening on 127.0.0.1, I'm just not sure what I'm doing wrong.
 
I haven't a damn clue, but it can't be a universal problem since the same code runs fine on my machine, also running 10.3.4.
 
I think I found it. I have the sockaddr_in as a local variable. Zeroing the struct before using it makes the bind() work. Must be junk in the struct (not unexpected) and the system call isn't ignoring it. Not sure what the POSIX/etc. specs say about that, but I've never had to zero it before.

Does it do this on your machine (do a memset(&addr, 0xff, sizeof addr) for example)?
 
As a matter of fact, the first line in my little test is "bzero(&addr.sin_zero, sizeof addr.sin_zero)" I thought you had omitted it for clarity. Since the field is named sin_zero, pretty much every socket guide I found fills it with zeroes, even though the latest POSIX spec omits the field entirely. I'm not sure why Apple's implementation isn't ignoring it, but you should zero it anyway.
 
Back
Top