[PYTHON-CRYPTO] m2crypto - close_wait when running echod_async
CARNES, MARK E (MARK)
carnesm at LUCENT.COM
Tue Jun 22 01:54:19 CEST 2004
I've been looking at a server that is using the SSL.ssl_dispatcher and asyncore.dispatcher, and noticed
file descriptors that aren't being closed. I went back and ran the echod_async example from the demo
directory and interestingly enough got the same result.
It looks like the socket is never being closed on the server side. If I manually go do a self.socket.socket.close()
I can get it to go away, but it looks like it normally wouldn't call that method unless it goes through the __del__
method in Connection, and the reference count was never going to 0.
The end result is that the "Connection" class self references its own methods "self._write_bio", and "self._write_nbio",
which causes a circular reference and if you don't have garbage collection enabled, this object never gets collected.
I tested a variation of "Connection" where I just created a "self.mode" and corresponding "self.send", "self.write", "self.recv",
and "self.read" methods instead of using the method references.
Is there a better way to approach this problem?
Here's the code I changed
-------------------------------------------------------------------------------------------------------------------------------------------------------------
<<snip>>
class Connection:
"""An SSL connection."""
def __init__(self, ctx, sock=None):
self.ctx = ctx
self.ssl = m2.ssl_new(self.ctx.ctx)
if sock is not None:
self.socket = sock
else:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._fileno = self.socket.fileno()
self.mode = 0 # -- ADDED
<<snip>>
def setblocking(self, mode):
"""Set this connection's underlying socket to _mode_."""
self.socket.setblocking(mode)
self.mode = mode # -- ADDED
# if mode: -- REMOVED
# self.send = self.write = self._write_bio -- REMOVED
# self.recv = self.read = self._read_bio -- REMOVED
# else: -- REMOVED
# self.send = self.write = self._write_nbio -- REMOVED
# self.recv = self.read = self._read_nbio -- REMOVED
# NEW METHODS FOLLOW
def send(self, data):
if self.mode:
return self._write_bio(data)
else:
return self._write_nbio(data)
def write(self, data):
if self.mode:
return self._write_bio(data)
else:
return self._write_nbio(data)
def recv(self, size=1024):
if self.mode:
return self._read_bio(size)
else:
return self._read_nbio(size)
def read(self, size=1024):
if self.mode:
return self._read_bio(size)
else:
return self._read_nbio(size)
# END NEW METHODS
<<snip>>
More information about the python-crypto
mailing list