Excerpts from David Reiss's message of Thu Jan 14 14:47:20 -0600 2010:
> It's not expected behavior. It is highly unlikely to be related to the
> generated code
> (TSocket is not generated). I assume the TServerSocket code is doing
> something
> to make
> FreeBSD think it only wants IPv6. I'm not sure what the fix is, though.
I ran into this a long time ago and never got around to filing a bug report.
One work around is to change the sysctl variable that prohibits v6 sockets
from also listening on v4:
sysctl -w net.inet6.ip6.v6only=0
This has security implications that I can't recall the full details of, so I
came up with a more flexible solution.
However I think this might be due to some strange behavior in TSocket.py. The
listen method for TServerSocket has this odd bit in it (lines 121-125 of
TSocket.py from trunk):
def listen(self):
res0 = self._resolveAddr()
for res in res0:
if res[0] is socket.AF_INET6 or res is res0[-1]:
break
I read this as take the first v6 address you find or the last address you
find. Seems kind of weird to prefer IPv6 at this point.
I have a subclass of TServerSocket that I use that allows me to specify hints
for what kind of socket to listen on. So in my code I call MyTServerSocket
with hints={'family': socket.AF_INET} so that I bind the the v4 address.
Hope that helps. FWIW I think the TServerSocket class should implement
something like this. With a little arm twisting I could probably submit a
patch...
Jon
-- snip --
class MyTServerSocket(TServerSocket):
def __init__(self, port, host='0.0.0.0', hints={}):
self.host = host
self.port = port
self.hints = {
'family': socket.AF_UNSPEC,
'socktype': socket.SOCK_STREAM,
'proto': 0,
'flags': socket.AI_PASSIVE}
self.hints.update(hints)
TServerSocket.__init__(self, port)
def listen(self):
res0 = socket.getaddrinfo(None, self.port, self.hints['family'],
self.hints['socktype'], self.hints['proto'],
self.hints['flags'])
for res in res0:
if res[0] is socket.AF_INET6 or res is res0[-1]:
break
self.handle = socket.socket(res[0], res[1])
self.handle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if hasattr(self.handle, 'set_timeout'):
self.handle.set_timeout(None)
self.handle.bind(res[4])
self.handle.listen(128)