summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames E. Blair <corvus@inaugust.com>2020-06-27 08:07:45 -0700
committerGitHub <noreply@github.com>2020-06-27 17:07:45 +0200
commitcbdc4749edb5879099c1f9b832c055d9eeb52dea (patch)
tree054114dd6d8d72c8cd27724b5023f35fdaefe14e
parent4e32e4d506be79f730d20f653cb7dffaf86c8dfc (diff)
downloadkazoo-cbdc4749edb5879099c1f9b832c055d9eeb52dea.tar.gz
fix(core): handle SSL_WANT_READ/WRITE errors (#619)
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>
-rw-r--r--kazoo/protocol/connection.py19
1 files changed, 17 insertions, 2 deletions
diff --git a/kazoo/protocol/connection.py b/kazoo/protocol/connection.py
index b4320f2..fc3586c 100644
--- a/kazoo/protocol/connection.py
+++ b/kazoo/protocol/connection.py
@@ -6,6 +6,7 @@ import logging
import random
import select
import socket
+import ssl
import sys
import time
@@ -247,7 +248,14 @@ class ConnectionHandler(object):
# 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)
@@ -319,7 +327,14 @@ class ConnectionHandler(object):
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