@@ -128,6 +128,77 @@ defmodule ExICE.Priv.ICEAgentTest do
128128 assert cand_pair . remote_cand_id == r_cand . id
129129 end
130130
131+ test "with duplicated prflx candidate" , % { ice_agent: ice_agent } do
132+ # Try to add a remote host candidate that has already been discovered as prflx candidate.
133+ # This should result in updating candidate's type and priority and pair's priority.
134+ # Also, selected_pair_id should change.
135+ assert % { } == ice_agent . remote_cands
136+ assert % { } == ice_agent . checklist
137+
138+ # prepare candiadtes
139+ remote_cand1 =
140+ ExICE.Candidate . new ( :host , address: { 192 , 168 , 0 , 2 } , port: 8445 , priority: 123 )
141+
142+ remote_cand2 =
143+ ExICE.Candidate . new ( :host , address: { 192 , 168 , 0 , 3 } , port: 8445 , priority: 122 )
144+
145+ [ socket ] = ice_agent . sockets
146+
147+ # discover prflx candidate
148+ req =
149+ binding_request (
150+ ice_agent . role ,
151+ ice_agent . tiebreaker ,
152+ ice_agent . remote_ufrag ,
153+ ice_agent . local_ufrag ,
154+ ice_agent . local_pwd ,
155+ priority: 120
156+ )
157+
158+ ice_agent =
159+ ICEAgent . handle_udp ( ice_agent , socket , remote_cand1 . address , remote_cand1 . port , req )
160+
161+ assert [ prflx_cand ] = Map . values ( ice_agent . remote_cands )
162+ assert [ prflx_pair ] = Map . values ( ice_agent . checklist )
163+ assert prflx_cand . type == :prflx
164+ prflx_pair = % CandidatePair { prflx_pair | state: :succeeded , valid?: true }
165+ ice_agent = put_in ( ice_agent . checklist [ prflx_pair . id ] , prflx_pair )
166+
167+ # add another remote candidate that will result in higher pair priority
168+ ice_agent = ICEAgent . add_remote_candidate ( ice_agent , remote_cand2 )
169+
170+ host_pair =
171+ Enum . find ( Map . values ( ice_agent . checklist ) , fn pair ->
172+ pair . remote_cand_id == remote_cand2 . id
173+ end )
174+
175+ assert host_pair . priority > prflx_pair . priority
176+ host_pair = % CandidatePair { host_pair | state: :succeeded , valid?: true }
177+ ice_agent = put_in ( ice_agent . checklist [ host_pair . id ] , host_pair )
178+ ice_agent = % ICEAgent { ice_agent | selected_pair_id: host_pair . id }
179+
180+ # try to add host candidate that is the same as prflx candidate
181+ ice_agent = ICEAgent . add_remote_candidate ( ice_agent , remote_cand1 )
182+
183+ host_pair2 =
184+ Enum . find ( Map . values ( ice_agent . checklist ) , fn pair ->
185+ pair . remote_cand_id == prflx_cand . id
186+ end )
187+
188+ # assert that prflx candidate change its type and priority, and the relevant pair
189+ # also changed its priority and became a new selected pair
190+ host_cand =
191+ Enum . find ( Map . values ( ice_agent . remote_cands ) , fn cand ->
192+ cand . id == prflx_cand . id
193+ end )
194+
195+ assert host_cand . type == :host
196+ assert host_cand . priority > prflx_cand . priority
197+ assert host_pair2 . priority > prflx_pair . priority
198+ assert host_pair2 . priority > host_pair . priority
199+ assert ice_agent . selected_pair_id == host_pair2 . id
200+ end
201+
131202 test "with duplicated remote candidate" , % { ice_agent: ice_agent } do
132203 ice_agent = ICEAgent . add_remote_candidate ( ice_agent , @ remote_cand )
133204 ice_agent = ICEAgent . add_remote_candidate ( ice_agent , @ remote_cand )
@@ -2566,7 +2637,7 @@ defmodule ExICE.Priv.ICEAgentTest do
25662637 Message . new ( % Type { class: :indication , method: :binding } ) |> Message . encode ( )
25672638 end
25682639
2569- defp binding_request ( role , tiebreaker , local_ufrag , remote_ufrag , remote_pwd ) do
2640+ defp binding_request ( role , tiebreaker , local_ufrag , remote_ufrag , remote_pwd , opts \\ [ ] ) do
25702641 ice_attrs =
25712642 if role == :controlled do
25722643 [ % ICEControlling { tiebreaker: tiebreaker + 1 } , % UseCandidate { } ]
@@ -2577,7 +2648,7 @@ defmodule ExICE.Priv.ICEAgentTest do
25772648 attrs =
25782649 [
25792650 % Username { value: "#{ remote_ufrag } :#{ local_ufrag } " } ,
2580- % Priority { priority: 1234 }
2651+ % Priority { priority: opts [ :priority ] || 1234 }
25812652 ] ++ ice_attrs
25822653
25832654 request =
0 commit comments