SSL socket blocking error handling

This commit is contained in:
Peter Šurda 2017-02-07 13:00:24 +01:00
parent ddc0ca5ede
commit 15c620dcc2
Signed by: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
2 changed files with 34 additions and 10 deletions

View File

@ -86,11 +86,11 @@ class receiveDataThread(threading.Thread):
while state.shutdown == 0:
dataLen = len(self.data)
try:
ssl = False
isSSL = False
if ((self.services & protocol.NODE_SSL == protocol.NODE_SSL) and
self.connectionIsOrWasFullyEstablished and
protocol.haveSSL(not self.initiatedConnection)):
ssl = True
isSSL = True
dataRecv = self.sslSock.recv(throttle.ReceiveThrottle().chunkSize)
else:
dataRecv = self.sock.recv(throttle.ReceiveThrottle().chunkSize)
@ -99,13 +99,21 @@ class receiveDataThread(threading.Thread):
except socket.timeout:
logger.error ('Timeout occurred waiting for data from ' + str(self.peer) + '. Closing receiveData thread. (ID: ' + str(id(self)) + ')')
break
except socket.error as err:
if err.errno == errno.EWOULDBLOCK:
if ssl:
except ssl.SSLError as err:
if err.errno == ssl.SSL_ERROR_WANT_READ:
select.select([self.sslSock], [], [], 10)
else:
select.select([self.sock], [], [], 10)
logger.error('sock.recv retriable error')
logger.debug('sock.recv retriable SSL error')
continue
logger.error ('SSL error: %i/%s', err.errno, str(err))
break
except socket.error as err:
if err.errno in (errno.EAGAIN, errno.EWOULDBLOCK):
select.select([self.sslSock if isSSL else self.sock], [], [], 10)
logger.debug('sock.recv retriable error')
continue
if sys.platform.startswith('win') and err.errno in (errno.WSAEAGAIN, errno.WSAEWOULDBLOCK):
select.select([self.sslSock if isSSL else self.sock], [], [], 10)
logger.debug('sock.recv retriable error')
continue
logger.error('sock.recv error. Closing receiveData thread (' + str(self.peer) + ', Thread ID: ' + str(id(self)) + ').' + str(err.errno) + "/" + str(err))
if self.initiatedConnection and not self.connectionIsOrWasFullyEstablished:

View File

@ -5,8 +5,10 @@ import Queue
from struct import unpack, pack
import hashlib
import random
import sys
import select
import socket
from ssl import SSLError, SSL_ERROR_WANT_WRITE
import sys
from helper_generic import addDataPadding
from class_objectHashHolder import *
@ -78,17 +80,31 @@ class sendDataThread(threading.Thread):
return
while self.buffer and state.shutdown == 0:
isSSL = False
try:
if ((self.services & protocol.NODE_SSL == protocol.NODE_SSL) and
self.connectionIsOrWasFullyEstablished and
protocol.haveSSL(not self.initiatedConnection)):
isSSL = True
amountSent = self.sslSock.send(self.buffer[:throttle.SendThrottle().chunkSize])
else:
amountSent = self.sock.send(self.buffer[:throttle.SendThrottle().chunkSize])
except socket.timeout:
continue
except SSLError as e:
if e.errno == SSL_ERROR_WANT_WRITE:
select.select([], [self.sslSock], [], 10)
logger.debug('sock.recv retriable SSL error')
continue
raise
except socket.error as e:
if e.errno == errno.EAGAIN:
if e.errno in (errno.EAGAIN, errno.EWOULDBLOCK):
select.select([], [self.sslSock if isSSL else self.sock], [], 10)
logger.debug('sock.recv retriable error')
continue
if sys.platform.startswith('win') and e.errno in (errno.WSAEAGAIN, errno.WSAEWOULDBLOCK):
select.select([], [self.sslSock if isSSL else self.sock], [], 10)
logger.debug('sock.recv retriable error')
continue
raise
throttle.SendThrottle().wait(amountSent)