Make the ssl handshake non blocking.
This commit is contained in:
parent
ad5472d5f2
commit
d83c25e709
3 changed files with 103 additions and 58 deletions
102
main.py
102
main.py
|
@ -127,40 +127,85 @@ def wrap_socket(server, file_descriptor):
|
||||||
else:
|
else:
|
||||||
sock = temp_socket
|
sock = temp_socket
|
||||||
|
|
||||||
try:
|
sock.setblocking(False)
|
||||||
start = time.time()
|
|
||||||
message = "{prefix}matrix: Doing SSL handshake...".format(
|
message = "{prefix}matrix: Doing SSL handshake...".format(
|
||||||
prefix=W.prefix("network"))
|
prefix=W.prefix("network"))
|
||||||
|
|
||||||
W.prnt(server.server_buffer, message)
|
W.prnt(server.server_buffer, message)
|
||||||
|
|
||||||
# TODO this blocks currently
|
|
||||||
ssl_socket = server.ssl_context.wrap_socket(
|
ssl_socket = server.ssl_context.wrap_socket(
|
||||||
sock,
|
sock,
|
||||||
|
do_handshake_on_connect=False,
|
||||||
server_hostname=server.address) # type: ssl.SSLSocket
|
server_hostname=server.address) # type: ssl.SSLSocket
|
||||||
|
|
||||||
cipher = ssl_socket.cipher()
|
server.socket = ssl_socket
|
||||||
|
|
||||||
|
try_ssl_handshake(server)
|
||||||
|
|
||||||
|
|
||||||
|
@utf8_decode
|
||||||
|
def ssl_fd_cb(server_name, file_descriptor):
|
||||||
|
server = SERVERS[server_name]
|
||||||
|
|
||||||
|
if server.ssl_hook:
|
||||||
|
W.unhook(server.ssl_hook)
|
||||||
|
server.ssl_hook = None
|
||||||
|
|
||||||
|
try_ssl_handshake(server)
|
||||||
|
|
||||||
|
return W.WEECHAT_RC_OK
|
||||||
|
|
||||||
|
|
||||||
|
def try_ssl_handshake(server):
|
||||||
|
socket = server.socket
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
socket.do_handshake()
|
||||||
|
|
||||||
|
cipher = socket.cipher()
|
||||||
cipher_message = ("{prefix}matrix: Connected using {tls}, and "
|
cipher_message = ("{prefix}matrix: Connected using {tls}, and "
|
||||||
"{bit} bit {cipher} cipher suite.").format(
|
"{bit} bit {cipher} cipher suite.").format(
|
||||||
prefix=W.prefix("network"),
|
prefix=W.prefix("network"),
|
||||||
tls=cipher[1],
|
tls=cipher[1],
|
||||||
bit=cipher[2],
|
bit=cipher[2],
|
||||||
cipher=cipher[0])
|
cipher=cipher[0])
|
||||||
|
|
||||||
W.prnt(server.server_buffer, cipher_message)
|
W.prnt(server.server_buffer, cipher_message)
|
||||||
|
|
||||||
# TODO print out the certificates
|
# TODO print out the certificates
|
||||||
# cert = ssl_socket.getpeercert()
|
# cert = socket.getpeercert()
|
||||||
# W.prnt(server.server_buffer, pprint.pformat(cert))
|
# W.prnt(server.server_buffer, pprint.pformat(cert))
|
||||||
|
|
||||||
server.lag = (time.time() - start) * 1000
|
finalize_connection(server)
|
||||||
W.bar_item_update("lag")
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except ssl.SSLWantReadError:
|
||||||
|
hook = W.hook_fd(
|
||||||
|
server.socket.fileno(),
|
||||||
|
1, 0, 0,
|
||||||
|
"ssl_fd_cb",
|
||||||
|
server.name
|
||||||
|
)
|
||||||
|
server.ssl_hook = hook
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
except ssl.SSLWantWriteError:
|
||||||
|
hook = W.hook_fd(
|
||||||
|
server.socket.fileno(),
|
||||||
|
0, 1, 0,
|
||||||
|
"ssl_fd_cb",
|
||||||
|
server.name
|
||||||
|
)
|
||||||
|
server.ssl_hook = hook
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
return ssl_socket
|
|
||||||
# TODO add finer grained error messages with the subclass exceptions
|
|
||||||
except ssl.SSLError as error:
|
except ssl.SSLError as error:
|
||||||
server_buffer_prnt(server, str(error))
|
server_buffer_prnt(server, str(error))
|
||||||
return None
|
matrix_server_reconnect(server)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
@utf8_decode
|
@utf8_decode
|
||||||
|
@ -230,18 +275,7 @@ def receive_cb(server_name, file_descriptor):
|
||||||
return W.WEECHAT_RC_OK
|
return W.WEECHAT_RC_OK
|
||||||
|
|
||||||
|
|
||||||
@utf8_decode
|
def finalize_connection(server):
|
||||||
def connect_cb(data, status, gnutls_rc, sock, error, ip_address):
|
|
||||||
# pylint: disable=too-many-arguments,too-many-branches
|
|
||||||
status_value = int(status) # type: int
|
|
||||||
server = SERVERS[data]
|
|
||||||
|
|
||||||
if status_value == W.WEECHAT_HOOK_CONNECT_OK:
|
|
||||||
file_descriptor = int(sock) # type: int
|
|
||||||
sock = wrap_socket(server, file_descriptor)
|
|
||||||
|
|
||||||
if sock:
|
|
||||||
server.socket = sock
|
|
||||||
hook = W.hook_fd(
|
hook = W.hook_fd(
|
||||||
server.socket.fileno(),
|
server.socket.fileno(),
|
||||||
1, 0, 0,
|
1, 0, 0,
|
||||||
|
@ -262,14 +296,24 @@ def connect_cb(data, status, gnutls_rc, sock, error, ip_address):
|
||||||
server.connected = True
|
server.connected = True
|
||||||
server.connecting = False
|
server.connecting = False
|
||||||
server.reconnect_count = 0
|
server.reconnect_count = 0
|
||||||
server.numeric_address = ip_address
|
|
||||||
|
|
||||||
server_buffer_set_title(server)
|
|
||||||
|
|
||||||
if not server.access_token:
|
if not server.access_token:
|
||||||
matrix_login(server)
|
matrix_login(server)
|
||||||
else:
|
|
||||||
matrix_server_reconnect(server)
|
|
||||||
|
@utf8_decode
|
||||||
|
def connect_cb(data, status, gnutls_rc, sock, error, ip_address):
|
||||||
|
# pylint: disable=too-many-arguments,too-many-branches
|
||||||
|
status_value = int(status) # type: int
|
||||||
|
server = SERVERS[data]
|
||||||
|
|
||||||
|
if status_value == W.WEECHAT_HOOK_CONNECT_OK:
|
||||||
|
file_descriptor = int(sock) # type: int
|
||||||
|
server.numeric_address = ip_address
|
||||||
|
server_buffer_set_title(server)
|
||||||
|
|
||||||
|
wrap_socket(server, file_descriptor)
|
||||||
|
|
||||||
return W.WEECHAT_RC_OK
|
return W.WEECHAT_RC_OK
|
||||||
|
|
||||||
elif status_value == W.WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND:
|
elif status_value == W.WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND:
|
||||||
|
|
|
@ -48,6 +48,7 @@ class MatrixServer:
|
||||||
self.buffers = dict() # type: Dict[str, weechat.buffer]
|
self.buffers = dict() # type: Dict[str, weechat.buffer]
|
||||||
self.server_buffer = None # type: weechat.buffer
|
self.server_buffer = None # type: weechat.buffer
|
||||||
self.fd_hook = None # type: weechat.hook
|
self.fd_hook = None # type: weechat.hook
|
||||||
|
self.ssl_hook = None # type: weechat.hook
|
||||||
self.timer_hook = None # type: weechat.hook
|
self.timer_hook = None # type: weechat.hook
|
||||||
self.numeric_address = "" # type: str
|
self.numeric_address = "" # type: str
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ def server_buffer_set_title(server):
|
||||||
else:
|
else:
|
||||||
ip_string = ""
|
ip_string = ""
|
||||||
|
|
||||||
title = ("Matrix: {address}/{port}{ip}").format(
|
title = ("Matrix: {address}:{port}{ip}").format(
|
||||||
address=server.address,
|
address=server.address,
|
||||||
port=server.port,
|
port=server.port,
|
||||||
ip=ip_string)
|
ip=ip_string)
|
||||||
|
|
Loading…
Reference in a new issue