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)

Reply via email to