@@ -1371,7 +1371,24 @@ defmodule ExICE.Priv.ICEAgentTest do
1371
1371
assert new_pair . responses_received == pair . responses_received + 1
1372
1372
end
1373
1373
1374
- test "Success response with the address of a local candidate from a different socket." do
1374
+ test "success response with the xor address of a local candidate with a different socket." do
1375
+ # This test checks a specific scenario where one of the local candidates uses a socket opened on a bridge interface:
1376
+
1377
+ # L - local side
1378
+ # R - remote side
1379
+ # RC1 - remote candidate
1380
+
1381
+ # 1. L opens socket on interface 1 (I1), port 5000 - first local candidate (LC1)
1382
+ # 2. L opens socket on interface 2 (I2), port 5000 - second local candidate (LC2)
1383
+ # 3. L sends a connection check from LC1 to RC1. Given LC1 operates via I1, which is a bridge interface, its source address is rewritten to I2
1384
+ # 4. R perceives the request from L as originating from I2, port 5000, and responds successfully to I2, port 5000
1385
+ # 5. This response arrives to the I1 port 5000. L notices that R recognized it as coming from I2, port 5000
1386
+ # 6. L chooses to use LC1 and RC1 as the discovered pair because we know that I1 is a bridge interface.
1387
+
1388
+ # Note: If we were to use LC2 and RC1 as the discovered pair
1389
+ # we would have different sockets between the succeeded and discovered pairs, which would cause a runtime error.
1390
+
1391
+ # Setup ice_agent to have two local candidates
1375
1392
ice_agent =
1376
1393
ICEAgent . new (
1377
1394
controlling_process: self ( ) ,
@@ -1384,25 +1401,29 @@ defmodule ExICE.Priv.ICEAgentTest do
1384
1401
|> ICEAgent . gather_candidates ( )
1385
1402
|> ICEAgent . add_remote_candidate ( @ remote_cand )
1386
1403
1387
- sockets = ice_agent . sockets
1388
-
1404
+ # send connectivity check
1389
1405
ice_agent = ICEAgent . handle_ta_timeout ( ice_agent )
1390
- { req , req_socket } = find_binding_request ( sockets , ice_agent . remote_pwd )
1391
1406
1407
+ # find candidate pair on which connectivity check was sent
1408
+ { _pair_id , pair } =
1409
+ Enum . find ( ice_agent . checklist , fn { _pair_id , pair } -> pair . state == :in_progress end )
1410
+
1411
+ local_cand = Map . fetch! ( ice_agent . local_cands , pair . local_cand_id )
1412
+ req = read_binding_request ( local_cand . base . socket , ice_agent . remote_pwd )
1413
+
1414
+ # create a response that includes the address of the second local candidate and its corresponding socket
1392
1415
resp =
1393
1416
binding_response (
1394
1417
req . transaction_id ,
1395
1418
ice_agent . transport_module ,
1396
- # Send response with other socket address
1397
- # See: https://github.com/elixir-webrtc/ex_ice/issues/77
1398
- Enum . find ( sockets , & ( & 1 != req_socket ) ) ,
1419
+ Enum . find ( ice_agent . sockets , & ( & 1 != local_cand . base . socket ) ) ,
1399
1420
ice_agent . remote_pwd
1400
1421
)
1401
1422
1402
1423
ice_agent =
1403
1424
ICEAgent . handle_udp (
1404
1425
ice_agent ,
1405
- req_socket ,
1426
+ local_cand . base . socket ,
1406
1427
@ remote_cand . address ,
1407
1428
@ remote_cand . port ,
1408
1429
resp
@@ -1413,10 +1434,14 @@ defmodule ExICE.Priv.ICEAgentTest do
1413
1434
|> Map . values ( )
1414
1435
|> Enum . sort ( & ( & 1 . priority > & 2 . priority ) )
1415
1436
1437
+ # verify that discovered pair is the same as succeeded
1416
1438
assert pair_1 . state == :succeeded
1439
+ assert pair_1 . id == pair_1 . succeeded_pair_id
1417
1440
assert pair_1 . succeeded_pair_id == pair_1 . discovered_pair_id
1418
1441
1419
1442
assert pair_2 . state == :waiting
1443
+ assert pair_2 . succeeded_pair_id == nil
1444
+ assert pair_2 . discovered_pair_id == nil
1420
1445
end
1421
1446
1422
1447
test "bad request error response" , % { ice_agent: ice_agent , remote_cand: remote_cand } do
@@ -1793,22 +1818,6 @@ defmodule ExICE.Priv.ICEAgentTest do
1793
1818
end
1794
1819
end
1795
1820
1796
- defp find_binding_request ( sockets , remote_pwd ) do
1797
- { _req , _socket } =
1798
- Enum . find_value ( sockets , fn socket ->
1799
- packet = Transport.Mock . recv ( socket )
1800
-
1801
- case ExSTUN.Message . decode ( packet ) do
1802
- { :ok , req } ->
1803
- :ok = ExSTUN.Message . authenticate ( req , remote_pwd )
1804
- { req , socket }
1805
-
1806
- _other ->
1807
- nil
1808
- end
1809
- end )
1810
- end
1811
-
1812
1821
defp read_binding_request ( socket , remote_pwd ) do
1813
1822
packet = Transport.Mock . recv ( socket )
1814
1823
{ :ok , req } = ExSTUN.Message . decode ( packet )
0 commit comments