Skip to content

Commit

Permalink
fix(core): handle SSL_WANT_READ/WRITE errors (#619)
Browse files Browse the repository at this point in the history
This adds a simple recovery path in case an SSL connection receives
an SSL_WANT_READ or WRITE error.  Either error can occur while
reading or writing.  The error indicates that the underlying
operation should be retried after the socket is once again readable
or writable (per the error code).

Closes #618

Co-authored-by: James E. Blair <jeblair@redhat.com>
  • Loading branch information
jeblair and James E. Blair authored Jun 27, 2020
1 parent 4e32e4d commit cbdc474
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions kazoo/protocol/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import random
import select
import socket
import ssl
import sys
import time

Expand Down Expand Up @@ -247,7 +248,14 @@ def _read(self, length, timeout):
# have to check wlist and xlist as we don't set any
raise self.handler.timeout_exception(
"socket time-out during read")
chunk = self._socket.recv(remaining)
try:
chunk = self._socket.recv(remaining)
except ssl.SSLError as e:
if e.errno in (ssl.SSL_ERROR_WANT_READ,
ssl.SSL_ERROR_WANT_WRITE):
continue
else:
raise
if chunk == b'':
raise ConnectionDropped('socket connection broken')
msgparts.append(chunk)
Expand Down Expand Up @@ -319,7 +327,14 @@ def _write(self, msg, timeout):
raise self.handler.timeout_exception("socket time-out"
" during write")
msg_slice = buffer(msg, sent)
bytes_sent = self._socket.send(msg_slice)
try:
bytes_sent = self._socket.send(msg_slice)
except ssl.SSLError as e:
if e.errno in (ssl.SSL_ERROR_WANT_READ,
ssl.SSL_ERROR_WANT_WRITE):
continue
else:
raise
if not bytes_sent:
raise ConnectionDropped('socket connection broken')
sent += bytes_sent
Expand Down

0 comments on commit cbdc474

Please sign in to comment.