Fix no timeout for handshake (#176)

This commit is contained in:
Otto Winter 2022-02-09 16:29:50 +01:00 committed by GitHub
parent 02160847e7
commit 3752b8280e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 3 deletions

View File

@ -179,7 +179,7 @@ class APINoiseFrameHelper(APIFrameHelper):
_LOGGER.debug("Received frame %s", frame.hex())
return frame
async def perform_handshake(self, expected_name: Optional[str]) -> None:
async def _perform_handshake(self, expected_name: Optional[str]) -> None:
await self._write_frame(b"") # ClientHello
prologue = b"NoiseAPIInit" + b"\x00\x00"
@ -236,6 +236,13 @@ class APINoiseFrameHelper(APIFrameHelper):
_LOGGER.debug("Handshake complete!")
self._ready_event.set()
async def perform_handshake(self, expected_name: Optional[str]) -> None:
# Allow up to 60 seconds for handhsake
try:
await asyncio.wait_for(self._perform_handshake(expected_name), timeout=60.0)
except asyncio.TimeoutError as err:
raise HandshakeAPIError("Timeout during handshake") from err
async def write_packet(self, packet: Packet) -> None:
# Wait for handshake to complete
await self._ready_event.wait()

View File

@ -164,7 +164,7 @@ class APIConnection:
except asyncio.TimeoutError as err:
raise SocketAPIError(f"Timeout while connecting to {sockaddr}") from err
_LOGGER.debug("%s: Opened socket for", self._params.address)
_LOGGER.debug("%s: Opened socket", self._params.address)
async def _connect_init_frame_helper(self) -> None:
"""Step 3 in connect process: initialize the frame helper and init read loop."""
@ -266,7 +266,7 @@ class APIConnection:
"Connection can only be used once, connection is not in init state"
)
try:
async def _do_connect() -> None:
addr = await self._connect_resolve_host()
await self._connect_socket_connect(addr)
await self._connect_init_frame_helper()
@ -274,6 +274,12 @@ class APIConnection:
await self._connect_start_ping()
if login:
await self.login()
try:
# Allow 2 minutes for connect; this is only as a last measure
# to protect from issues if some part of the connect process mistakenly
# does not have a timeout
await asyncio.wait_for(_do_connect(), timeout=120.0)
except Exception: # pylint: disable=broad-except
# Always clean up the connection if an error occured during connect
self._connection_state = ConnectionState.CLOSED