From 2bcdfd069a546e3bd52c02e3e8079690a983257e Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Fri, 29 May 2020 19:46:32 +0200 Subject: [PATCH] Socket: Detect closed TCP connections. So far Limnoria relied on detecting 'ERROR :closing link' (see doError in src/irclib.py), but that's not a standard at all, and fails on Oragono; so we need to do this to check we're disconnected. Plus, parsing the argument of ERROR is awful in the first place. --- src/drivers/Socket.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/drivers/Socket.py b/src/drivers/Socket.py index c358f9f12..70e60e3d1 100644 --- a/src/drivers/Socket.py +++ b/src/drivers/Socket.py @@ -105,9 +105,11 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): return server def _handleSocketError(self, e): + # 'e is None' means the socket was closed. + # # (11, 'Resource temporarily unavailable') raised if connect # hasn't finished yet. We'll keep track of how many we get. - if e.args[0] != 11 or self.eagains > 120: + if e is None or e.args[0] != 11 or self.eagains > 120: drivers.log.disconnect(self.currentServer, e) if self in self._instances: self._instances.remove(self) @@ -195,7 +197,13 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): def _read(self): """Called by _select() when we can read data.""" try: - self.inbuffer += self.conn.recv(1024) + new_data = self.conn.recv(1024) + if not new_data: + # Socket was closed + self._handleSocketError(None) + return + + self.inbuffer += new_data self.eagains = 0 # If we successfully recv'ed, we can reset this. lines = self.inbuffer.split(b'\n') self.inbuffer = lines.pop()