On 20 Jun 2005, at 04:29, noreply / rubyforge.org wrote: > Bugs item #2047, was opened at 2005-06-20 12:24 > You can respond by visiting: > http://rubyforge.org/tracker/? > func=detail&atid=1698&aid=2047&group_id=426 > > Category: Standard Library > Group: None > Status: Open > Resolution: None > Priority: 3 > Submitted By: Brian Candler (bcandler) > Assigned to: Nobody (None) > Summary: TCPSocket fails to bind first time on certain FreeBSD configs > > Initial Comment: > I have some very strange reproducible behaviour with TCPSocket. It > differs > between two machines which are almost identical: one is FreeBSD-5.4- > RELEASE, > the other is FreeBSD-5.4-STABLE dating from only a week or so after > 5.4-RELEASE. Both report Ruby version as > "ruby 1.8.2 (2004-12-25) [i386-freebsd5]" > > The 5.4-RELEASE machine is running a GENERIC kernel with IPv6 > enabled. The > 5.4-STABLE machine has a slightly customised kernel, with IPv6 > turned off. > This is the only thing which I can imagine is significant. > > Now, it's the 5.4-STABLE machine (no IPv6) which is being strange: > > $ irb > irb(main):001:0> require 'socket' > => true > irb(main):002:0> a = TCPServer.new(1234) > => #<TCPServer:0x813aed0> > irb(main):003:0> > > At this point, you'd expect the server to be listening on port 1234. > However, it isn't: in another window I can try No, it is. Remove -4 from sockstat args... > $ telnet localhost 1234 > Trying 127.0.0.1... > telnet: connect to address 127.0.0.1: Connection refused > telnet: Unable to connect to remote host > $ sockstat -4l > USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN > ADDRESS > mailnull exim-4.50- 432 4 tcp4 *:25 *:* > root sshd 393 4 tcp4 *:22 *:* > root lpd 363 7 tcp4 *:515 *:* > root syslogd 266 6 udp4 *:514 *:* $ sockstat -l | grep 1234 eric ruby18 28234 3 tcp6 *:1234 *:* $ telnet localhost 1234 Trying ::1... Connected to localhost.coop.robotcoop.com. Escape character is '^]'. ^] telnet> quit Connection closed. > However, as soon as I create a *second* TCPServer object, it works. > > This is completely repeatable. Now: if I give an IP address > explicitly to > bind to, it's OK: [snip] Now it is listening on *two* ports: $ sockstat -l | grep 1234 eric ruby18 28325 3 tcp4 *:1234 *:* eric ruby18 28234 3 tcp6 *:1234 *:* > So I have a workaround which solves my problem - but it looks like > there's something strange going on under the surface. You need to bind both IPv6 and IPv4 addresses on IPv6-enabled hosts. The following should work on both IPv4-only and IPv4/IPv6 hosts (I took it from WEBrick): $ cat x.rb require 'socket' res = Socket.getaddrinfo(nil, 1234, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE) sockets = [] res.each do |ai| sockets << TCPServer.new(ai[3], ai[1]) end sleep 10 $ ruby x.rb & [2] 28585 $ sockstat -l | grep 1234 eric ruby 28585 3 tcp6 *:1234 *:* eric ruby 28585 4 tcp4 *:1234 *:* Also, what is in your /etc/hosts? $ cat /etc/hosts ::1 localhost.coop.robotcoop.com localhost 127.0.0.1 localhost.coop.robotcoop.com localhost -- Eric Hodel - drbrain / segment7.net - http://segment7.net FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04