You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using a TURN server that cannot be reached, Connection.gather_candidates() raises an exception. That makes the gathering failed even if the local candidates and/or STUN candidates were gathered successfully. Unreachable STUN server timeouts as expected.
This is problematic when the server goes down, or in case the local firewall is wrongly configured.
Versions
aioice==0.9.0 Python 3.11.1
To reproduce
Run the following program and wait for 60 seconds.
The same problem arises with turn_transport="tcp", just the timeout is longer (around 250s for me).
Another way of reproducing the issue is to use a working TURN server and block the outgoing traffic locally, e.g. iptables -A OUTPUT -p udp --dport 12345 -j REJECT.
Behavior
An exception is raised after 60 seconds
Traceback (most recent call last):
File "/home/novako/playground/webrtc/test_aioice_timeouts.py", line 21, in <module>
asyncio.run(main())
File "/home/novako/.pyenv/versions/3.11.1/lib/python3.11/asyncio/runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/home/novako/.pyenv/versions/3.11.1/lib/python3.11/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/novako/.pyenv/versions/3.11.1/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/home/novako/playground/webrtc/test_aioice_timeouts.py", line 17, in main
await connection.gather_candidates()
File "/home/novako/playground/venv/lib/python3.11/site-packages/aioice/ice.py", line 454, in gather_candidates
for candidates in await asyncio.gather(*coros):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/novako/playground/venv/lib/python3.11/site-packages/aioice/ice.py", line 940, in get_component_candidates
_, protocol = await turn.create_turn_endpoint(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/novako/playground/venv/lib/python3.11/site-packages/aioice/turn.py", line 441, in create_turn_endpoint
await turn_transport._connect()
File "/home/novako/playground/venv/lib/python3.11/site-packages/aioice/turn.py", line 390, in _connect
self.__relayed_address = await self.__inner_protocol.connect()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/novako/playground/venv/lib/python3.11/site-packages/aioice/turn.py", line 123, in connect
response, _ = await self.request_with_retry(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/novako/playground/venv/lib/python3.11/site-packages/aioice/turn.py", line 243, in request_with_retry
response, addr = await self.request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/novako/playground/venv/lib/python3.11/site-packages/aioice/turn.py", line 230, in request
return await transaction.run()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/novako/playground/venv/lib/python3.11/site-packages/aioice/stun.py", line 302, in run
return await self.__future
^^^^^^^^^^^^^^^^^^^
aioice.stun.TransactionTimeout: STUN transaction timed out
Expected behavior
The function does not raise an exception, it respects the timeout parameter and returns host and STUN candidates.
Analysis
Connection.gather_candidates() calls Connection.get_component_candidates() with default timeout=5 parameter. The latter method then does three things. First, it gathers host candidates, then it gathers STUN candidates, waiting for the results by asyncio.wait() using the timeout parameter, and finally it gathers TURN candidates. However, the timeout is not respected here, making the await turn.create_turn_endpoint() call block until an internal socket timeout is reached.
Proposed solution
With my limited knowledge of the library, I suggest using asyncio.wait() when creating the endpoint and only adding the candidates if the query has been successful. In worst case, when both STUN and TURN is unavailable, this would make the real time before the function times out double, so joining the both queries under a single asyncio.wait() may be in place.
The text was updated successfully, but these errors were encountered:
Description
When using a TURN server that cannot be reached,
Connection.gather_candidates()
raises an exception. That makes the gathering failed even if the local candidates and/or STUN candidates were gathered successfully. Unreachable STUN server timeouts as expected.This is problematic when the server goes down, or in case the local firewall is wrongly configured.
Versions
aioice==0.9.0
Python 3.11.1
To reproduce
Run the following program and wait for 60 seconds.
The same problem arises with
turn_transport="tcp"
, just the timeout is longer (around 250s for me).Another way of reproducing the issue is to use a working TURN server and block the outgoing traffic locally, e.g.
iptables -A OUTPUT -p udp --dport 12345 -j REJECT
.Behavior
An exception is raised after 60 seconds
Expected behavior
The function does not raise an exception, it respects the
timeout
parameter and returns host and STUN candidates.Analysis
Connection.gather_candidates()
callsConnection.get_component_candidates()
with defaulttimeout=5
parameter. The latter method then does three things. First, it gathers host candidates, then it gathers STUN candidates, waiting for the results byasyncio.wait()
using thetimeout
parameter, and finally it gathers TURN candidates. However, thetimeout
is not respected here, making theawait turn.create_turn_endpoint()
call block until an internal socket timeout is reached.Proposed solution
With my limited knowledge of the library, I suggest using
asyncio.wait()
when creating the endpoint and only adding the candidates if the query has been successful. In worst case, when both STUN and TURN is unavailable, this would make the real time before the function times out double, so joining the both queries under a singleasyncio.wait()
may be in place.The text was updated successfully, but these errors were encountered: