From the upstream bug: http://bugs.python.org/issue6706 An old bad design choice in asyncore is how it forces the user to override handle_accept() and then call self.accept() to obtain a socket pair. def handle_accept(self): conn, addr = self.accept() The documentation itself shows the code above as an example of how an asyncore-based server should handle an incoming connection. What the doc doesn't say is that the user calling self.accept() is exposed to different risks: - self.accept() can return None instead of a socket pair in which case TypeError is raised (see pyftpdlib bug: http://code.google.com/p/pyftpdlib/issues/detail?id=91) - ECONNABORTED can be raised. This is reproducible on Linux by hammering the server with nmap (see pyftpdlib bug: http://code.google.com/p/pyftpdlib/issues/detail?id=105) - EAGAIN can be raised too. I never experienced this error condition myself in pyftpdlib but by looking at twisted/internet/tcp.py it seems reasonable to catch EAGAIN too. - The resulting address can be None, which means that the connection didn't take place. This is reproducible by hammering the server with nmap (see pyftpdlib bug http://code.google.com/p/pyftpdlib/issues/detail?id=104). The right thing to do when one of such events occur is to "return" as no connection has really been established between client and server. Now, altough handling these kind of conditions is quite easy, the API design remains fundamentally wrong, as it forces the user to call accept(). As asyncore.py is structured right now the only chance the user has to properly accepting a connection is manually handling all these cases in his subclass.
Upstream has a fix for this now: http://svn.python.org/view?view=rev&revision=86084 It seems that the fix still can return None, which some clients will not handle gracefully. I suspect the solution is going to be to patch clients, not python itself.
Statement: This issue affects the version of the python package as shipped with Red Hat Enterprise Linux 4, 5, and 6. Due to the nature of this flaw, it cannot be fixed in the python language, but must be addressed in each module which calls accept().