Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to set up a simple web server on Mac OS X, and I keep getting an error when I run bind. Here's what I'm running (this transcript uses GNU Guile, but just as a convenient interface to posix).

(define addr (inet-aton "127.0.0.1"))                     ; get internal representation of 127.0.0.1
(define sockaddr (make-socket-address AF_INET addr 8080)) ; make a struct sockaddr
(define sock (socket PF_INET SOCK_STREAM 0))              ; make a socket
(bind sock sockaddr)                                      ; bind the socket to the address

That gives me the error In procedure bind: can't assign requested address.

So I tried it again allowing any address.

(define anyaddr (make-socket-address AF_INET INADDR_ANY 8080)) ; allow any address
(bind sock anyaddr)

And that works fine. But it's weird, because ifconfig lo0 says

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
  inet6 ::1 prefixlen 128 
  inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
  inet 127.0.0.1 netmask 0xff000000 

So the loopback device is assigned to 127.0.0.1. So my question is, why can't I bind to that address?

Thanks.

Update: the output of route get 127.0.0.1 is

   route to: localhost
destination: localhost
  interface: lo0
      flags: <UP,HOST,DONE,LOCAL>
 recvpipe  sendpipe  ssthresh  rtt,msec    rttvar  hopcount      mtu     expire
   49152     49152         0         0         0         0     16384         0 
share|improve this question
    
Is there something already listening on port 8080? What does netstat say? e.g. netstat -a -n -f inet | grep '127.0.0.1:8080' or similar. – Mikel Feb 6 '11 at 21:29
    
Mikel: that command produces no results. Running just netstat -a -n -f inet also produces nothing interesting: just some tcp connections to stackoverflow and a bunch of udp ports. – Noah Lavine Feb 6 '11 at 21:34
    
Oh, and running Guile with root privileges doesn't fix it. – Noah Lavine Feb 6 '11 at 21:45
up vote 2 down vote accepted

This isn't exactly an answer, since it doens't directly solve you problem...but it looks as if your problem is particular to guile. That is, on my OS X 10.6 system, I have the same problem you do using the guile code from you example. On the other hand, the following works just fine:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1', 8080))
s.listen(5)

c, addr = s.accept()
c.send('hello\n')
c.close()

If I run this code, I can see the socket listening:

netstat -f inet -an | grep 8080
tcp4       0      0  127.0.0.1.8080         *.*                    LISTEN

And connecting to port 8080 does what you would expect:

$ telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
Connection closed by foreign host.
share|improve this answer
    
Yep, I just replicated your results. It must be a problem with Guile. I'll talk to the development list and track it down. – Noah Lavine Feb 7 '11 at 0:36
    
Did you ever track this down? I'm having almost exactly the same problem, except that it's a different Lisp dialect (TXR Lisp), and the protocol is IPV4 UDP. The OS is MacOS 10.7.3 (Lion). I can bind a UDP socket to address 0, but not 127.0.0.1: can't assign requested address. The code runs fine on the 32 and 64 bit x86 Linux port of the language, as well as Solaris 10. – Kaz Mar 10 at 3:29
    
@Kaz - You need to post a new question (and not as an edit to the original question). – David Makogon Mar 10 at 5:26
    
@DavidMakogon Nonsense; it's almost certainly the same issue. I'm not about to post an exact duplicate question! Clearing the structure to all zero bytes before assigning the fields fixes it. – Kaz Mar 10 at 6:03
    
@Kaz Sorry but not nonsense. Your edit has already been rejected , as you posted your own question into someone else's. If it's the same question, then upvote the question. Otherwise... post a new question. No need to argue here anymore (where we're now overtaking someone's answer with this conversation). – David Makogon Mar 10 at 6:06

Indeed, in my case, the problem is with the uninitialized fields in the structure which have nothing to do with the semantic socket address.

I added a memset(&sa, 0, sizeof sa) and now it binds.

It is almost certainly the case that the Guile implementation was running into the same issue: initializing just the documented fields of struct sockaddr_in. The symptoms were exactly the same, in any case: INADDR_ANY binding, yet INADDR_LOOPBACK refusing with the same errno.

Edit: sorry if I'm unclear; I'm referring to something I added to the question which someone removed. Namely, I ran into exactly the same problem in the implementation of (by sheer coincidence) another Lisp dialect. I added my observations, along with some gdb debug session traces showing the contents of the struct sockaddr_in before the bind call. The address showed correctly initialized sin_family, sin_addr and sin_port fields. However, the sin_len field at the head of the structure (present on Darwin, absent on other platforms) was uninitialized, as well as a sin_zero padding array at the end.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.