@@ -2,7 +2,7 @@ defmodule ExICE.Priv.ICEAgentTest do
22 use ExUnit.Case , async: true
33
44 alias ExICE.Priv . { Candidate , CandidatePair , IfDiscovery , ICEAgent }
5- alias ExICE.Priv.Attribute . { ICEControlled , ICEControlling , Priority }
5+ alias ExICE.Priv.Attribute . { ICEControlled , ICEControlling , Priority , UseCandidate }
66 alias ExICE.Support.Transport
77
88 alias ExSTUN.Message
@@ -114,7 +114,7 @@ defmodule ExICE.Priv.ICEAgentTest do
114114 end
115115 end
116116
117- test "don 't add pairs with srflx local candidate to the checklist" do
117+ test "doesn 't add pairs with srflx local candidate to the checklist" do
118118 ice_agent =
119119 ICEAgent . new (
120120 controlling_process: self ( ) ,
@@ -150,6 +150,123 @@ defmodule ExICE.Priv.ICEAgentTest do
150150 assert pair . local_cand_id == host_cand . base . id
151151 end
152152
153+ test "forwards data received on a faild pair and re-schedules" do
154+ remote_cand = ExICE.Candidate . new ( :host , address: { 192 , 168 , 0 , 3 } , port: 8445 )
155+
156+ ice_agent =
157+ ICEAgent . new (
158+ controlling_process: self ( ) ,
159+ role: :controlling ,
160+ transport_module: Transport.Mock ,
161+ if_discovery_module: IfDiscovery.Mock
162+ )
163+ |> ICEAgent . set_remote_credentials ( "someufrag" , "somepwd" )
164+ |> ICEAgent . gather_candidates ( )
165+ |> ICEAgent . add_remote_candidate ( remote_cand )
166+
167+ [ socket ] = ice_agent . sockets
168+
169+ # mark pair as failed
170+ [ pair ] = Map . values ( ice_agent . checklist )
171+ ice_agent = put_in ( ice_agent . checklist [ pair . id ] , % { pair | state: :failed } )
172+
173+ # clear ta_timer, ignore outgoing binding request that has been generated
174+ ice_agent = ICEAgent . handle_ta_timeout ( ice_agent )
175+ assert ice_agent . ta_timer == nil
176+
177+ # feed some data
178+ ice_agent =
179+ ICEAgent . handle_udp ( ice_agent , socket , remote_cand . address , remote_cand . port , "some data" )
180+
181+ # assert that data has been passed
182+ assert_receive { :ex_ice , _pid , { :data , "some data" } }
183+
184+ # assert that pair is re-scheduled
185+ assert [ pair ] = Map . values ( ice_agent . checklist )
186+ assert pair . state == :waiting
187+ assert ice_agent . ta_timer != nil
188+ end
189+
190+ describe "re-schedules failed pair on incoming binding request" do
191+ test "with controlling ice agent" do
192+ remote_cand = ExICE.Candidate . new ( :host , address: { 192 , 168 , 0 , 3 } , port: 8445 )
193+
194+ ice_agent =
195+ ICEAgent . new (
196+ controlling_process: self ( ) ,
197+ role: :controlling ,
198+ transport_module: Transport.Mock ,
199+ if_discovery_module: IfDiscovery.Mock
200+ )
201+ |> ICEAgent . set_remote_credentials ( "someufrag" , "somepwd" )
202+ |> ICEAgent . gather_candidates ( )
203+ |> ICEAgent . add_remote_candidate ( remote_cand )
204+
205+ test_rescheduling ( ice_agent , remote_cand )
206+ end
207+
208+ test "with controlled ice agent" do
209+ remote_cand = ExICE.Candidate . new ( :host , address: { 192 , 168 , 0 , 3 } , port: 8445 )
210+
211+ ice_agent =
212+ ICEAgent . new (
213+ controlling_process: self ( ) ,
214+ role: :controlled ,
215+ transport_module: Transport.Mock ,
216+ if_discovery_module: IfDiscovery.Mock
217+ )
218+ |> ICEAgent . set_remote_credentials ( "someufrag" , "somepwd" )
219+ |> ICEAgent . gather_candidates ( )
220+ |> ICEAgent . add_remote_candidate ( remote_cand )
221+
222+ test_rescheduling ( ice_agent , remote_cand )
223+ end
224+
225+ defp test_rescheduling ( ice_agent , remote_cand ) do
226+ [ socket ] = ice_agent . sockets
227+
228+ # make sure we won't overflow when modifying tiebreakers later on
229+ ice_agent = % { ice_agent | tiebreaker: 100 }
230+
231+ # mark pair as failed
232+ [ pair ] = Map . values ( ice_agent . checklist )
233+ ice_agent = put_in ( ice_agent . checklist [ pair . id ] , % { pair | state: :failed } )
234+
235+ # clear ta_timer, ignore outgoing binding request that has been generated
236+ ice_agent = ICEAgent . handle_ta_timeout ( ice_agent )
237+ assert ice_agent . ta_timer == nil
238+
239+ # feed incoming binding request
240+ ice_attrs =
241+ if ice_agent . role == :controlled do
242+ [ % ICEControlling { tiebreaker: ice_agent . tiebreaker + 1 } , % UseCandidate { } ]
243+ else
244+ [ % ICEControlled { tiebreaker: ice_agent . tiebreaker - 1 } ]
245+ end
246+
247+ attrs =
248+ [
249+ % Username { value: "#{ ice_agent . local_ufrag } :someufrag" } ,
250+ % Priority { priority: 1234 }
251+ ] ++ ice_attrs
252+
253+ request =
254+ Message . new ( % Type { class: :request , method: :binding } , attrs )
255+ |> Message . with_integrity ( ice_agent . local_pwd )
256+ |> Message . with_fingerprint ( )
257+
258+ raw_request = Message . encode ( request )
259+
260+ ice_agent =
261+ ICEAgent . handle_udp ( ice_agent , socket , remote_cand . address , remote_cand . port , raw_request )
262+
263+ # assert that pair is re-scheduled
264+ assert [ pair ] = Map . values ( ice_agent . checklist )
265+ assert pair . state == :waiting
266+ assert ice_agent . ta_timer != nil
267+ end
268+ end
269+
153270 describe "sends keepalives" do
154271 setup do
155272 remote_cand = ExICE.Candidate . new ( :host , address: { 192 , 168 , 0 , 2 } , port: 8445 )
0 commit comments