Timeout handling and ping

- timeouts after the connection is established will trigger a ping
- previously they were handled as unrecoverable errors
This commit is contained in:
Peter Šurda 2017-02-07 16:06:24 +01:00
parent 15c620dcc2
commit 413419c858
Signed by: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87

View File

@ -97,14 +97,21 @@ class receiveDataThread(threading.Thread):
self.data += dataRecv self.data += dataRecv
throttle.ReceiveThrottle().wait(len(dataRecv)) throttle.ReceiveThrottle().wait(len(dataRecv))
except socket.timeout: except socket.timeout:
logger.error ('Timeout occurred waiting for data from ' + str(self.peer) + '. Closing receiveData thread. (ID: ' + str(id(self)) + ')') if self.connectionIsOrWasFullyEstablished:
self.sendping("Still around!")
continue
logger.error("Timeout during protocol initialisation")
break break
except ssl.SSLError as err: except ssl.SSLError as err:
if err.errno == ssl.SSL_ERROR_WANT_READ: if err.errno == ssl.SSL_ERROR_WANT_READ:
select.select([self.sslSock], [], [], 10) select.select([self.sslSock], [], [], 10)
logger.debug('sock.recv retriable SSL error') logger.debug('sock.recv retriable SSL error')
continue continue
logger.error ('SSL error: %i/%s', err.errno, str(err)) if err.errno is None and 'timed out' in str(err):
if self.connectionIsOrWasFullyEstablished:
self.sendping("Still around!")
continue
logger.error ('SSL error: %i/%s', err.errno if err.errno else 0, str(err))
break break
except socket.error as err: except socket.error as err:
if err.errno in (errno.EAGAIN, errno.EWOULDBLOCK): if err.errno in (errno.EAGAIN, errno.EWOULDBLOCK):
@ -223,8 +230,10 @@ class receiveDataThread(threading.Thread):
self.recobject(payload) self.recobject(payload)
elif command == 'ping': elif command == 'ping':
self.sendpong(payload) self.sendpong(payload)
#elif command == 'pong': elif command == 'pong':
# pass pass
else:
logger.info("Unknown command %s, ignoring", command)
except varintDecodeError as e: except varintDecodeError as e:
logger.debug("There was a problem with a varint while processing a message from the wire. Some details: %s" % e) logger.debug("There was a problem with a varint while processing a message from the wire. Some details: %s" % e)
except Exception as e: except Exception as e:
@ -240,11 +249,13 @@ class receiveDataThread(threading.Thread):
pass pass
self.processData() self.processData()
def sendpong(self, payload): def sendpong(self, payload):
logger.debug('Sending pong') logger.debug('Sending pong')
self.sendDataThreadQueue.put((0, 'sendRawData', protocol.CreatePacket('pong', payload))) self.sendDataThreadQueue.put((0, 'sendRawData', protocol.CreatePacket('pong', payload)))
def sendping(self, payload):
logger.debug('Sending ping')
self.sendDataThreadQueue.put((0, 'sendRawData', protocol.CreatePacket('ping', payload)))
def recverack(self): def recverack(self):
logger.debug('verack received') logger.debug('verack received')
@ -314,7 +325,7 @@ class receiveDataThread(threading.Thread):
shared.clientHasReceivedIncomingConnections = True shared.clientHasReceivedIncomingConnections = True
shared.UISignalQueue.put(('setStatusIcon', 'green')) shared.UISignalQueue.put(('setStatusIcon', 'green'))
self.sock.settimeout( self.sock.settimeout(
600) # We'll send out a pong every 5 minutes to make sure the connection stays alive if there has been no other traffic to send lately. 600) # We'll send out a ping every 5 minutes to make sure the connection stays alive if there has been no other traffic to send lately.
shared.UISignalQueue.put(('updateNetworkStatusTab', 'no data')) shared.UISignalQueue.put(('updateNetworkStatusTab', 'no data'))
logger.debug('Connection fully established with ' + str(self.peer) + "\n" + \ logger.debug('Connection fully established with ' + str(self.peer) + "\n" + \
'The size of the connectedHostsList is now ' + str(len(shared.connectedHostsList)) + "\n" + \ 'The size of the connectedHostsList is now ' + str(len(shared.connectedHostsList)) + "\n" + \