@@ -220,6 +220,11 @@ defmodule ExICE.Priv.ICEAgent do
220220 end
221221
222222 @ spec set_remote_credentials ( t ( ) , binary ( ) , binary ( ) ) :: t ( )
223+ def set_remote_credentials ( % __MODULE__ { state: :failed } = ice_agent , _ , _ ) do
224+ Logger . debug ( "Tried to set remote credentials in failed state. ICE restart needed. Ignoring." )
225+ ice_agent
226+ end
227+
223228 def set_remote_credentials (
224229 % __MODULE__ { remote_ufrag: nil , remote_pwd: nil } = ice_agent ,
225230 ufrag ,
@@ -249,6 +254,11 @@ defmodule ExICE.Priv.ICEAgent do
249254 end
250255
251256 @ spec gather_candidates ( t ( ) ) :: t ( )
257+ def gather_candidates ( % __MODULE__ { state: :failed } = ice_agent ) do
258+ Logger . warning ( "Can't gather candidates in state failed. ICE restart needed. Ignoring." )
259+ ice_agent
260+ end
261+
252262 def gather_candidates ( % __MODULE__ { gathering_state: :gathering } = ice_agent ) do
253263 Logger . warning ( "Can't gather candidates. Gathering already in progress. Ignoring." )
254264 ice_agent
@@ -311,6 +321,12 @@ defmodule ExICE.Priv.ICEAgent do
311321 end
312322
313323 @ spec add_remote_candidate ( t ( ) , Candidate . t ( ) ) :: t ( )
324+ def add_remote_candidate ( % __MODULE__ { state: :failed } = ice_agent , _ ) do
325+ # Completed state will be cought by the next clause
326+ Logger . debug ( "Can't add remote candidate in state failed. ICE restart needed. Ignoring." )
327+ ice_agent
328+ end
329+
314330 def add_remote_candidate ( % __MODULE__ { eoc: true } = ice_agent , remote_cand ) do
315331 Logger . warning ( """
316332 Received remote candidate after end-of-candidates. Ignoring.
@@ -361,6 +377,11 @@ defmodule ExICE.Priv.ICEAgent do
361377 end
362378
363379 @ spec end_of_candidates ( t ( ) ) :: t ( )
380+ def end_of_candidates ( % __MODULE__ { state: :failed } = ice_agent ) do
381+ Logger . debug ( "Can't set end-of-candidates flag in state failed. Ignoring." )
382+ ice_agent
383+ end
384+
364385 def end_of_candidates ( % __MODULE__ { role: :controlled } = ice_agent ) do
365386 Logger . debug ( "Setting end-of-candidates flag." )
366387 ice_agent = % { ice_agent | eoc: true }
@@ -418,7 +439,7 @@ defmodule ExICE.Priv.ICEAgent do
418439
419440 @ spec handle_ta_timeout ( t ( ) ) :: t ( )
420441 def handle_ta_timeout ( % __MODULE__ { state: state } = ice_agent )
421- when state . state in [ :completed , :failed ] do
442+ when state in [ :completed , :failed ] do
422443 Logger . warning ( """
423444 Ta timer fired in unexpected state: #{ state } .
424445 Trying to update gathering and connection states.
@@ -477,6 +498,11 @@ defmodule ExICE.Priv.ICEAgent do
477498 end
478499
479500 @ spec handle_eoc_timeout ( t ( ) ) :: t ( )
501+ def handle_eoc_timeout ( % __MODULE__ { state: :failed } = ice_agent ) do
502+ Logger . debug ( "EOC timer fired but we are in the failed state. Ignoring." )
503+ % { ice_agent | eoc_timer: nil }
504+ end
505+
480506 def handle_eoc_timeout ( % { eoc: true } = ice_agent ) do
481507 Logger . debug ( "EOC timer fired but EOC flag is already set. Ignoring." )
482508 % { ice_agent | eoc_timer: nil }
@@ -489,6 +515,12 @@ defmodule ExICE.Priv.ICEAgent do
489515 end
490516
491517 @ spec handle_pair_timeout ( t ( ) ) :: t ( )
518+ def handle_pair_timeout ( % __MODULE__ { state: state } = ice_agent )
519+ when state in [ :failed , :completed ] do
520+ Logger . debug ( "Pair timeout timer fired in state: #{ state } . Ignoring." )
521+ ice_agent
522+ end
523+
492524 def handle_pair_timeout ( ice_agent ) do
493525 start_pair_timer ( )
494526
@@ -564,8 +596,16 @@ defmodule ExICE.Priv.ICEAgent do
564596 { :ok , _pair } ->
565597 ice_agent
566598
599+ :error when ice_agent . state in [ :failed , :completed ] ->
600+ Logger . warning ( """
601+ Received keepalive request for non-existant candidate pair but we are in state: #{ ice_agent . state } . \
602+ Ignoring.\
603+ """ )
604+
605+ ice_agent
606+
567607 :error ->
568- Logger . warning ( "Received keepalive request for non-existant candidate pair" )
608+ Logger . warning ( "Received keepalive request for non-existant candidate pair. Ignoring. " )
569609 ice_agent
570610 end
571611 end
@@ -577,6 +617,10 @@ defmodule ExICE.Priv.ICEAgent do
577617 :inet . port_number ( ) ,
578618 binary ( )
579619 ) :: t ( )
620+ def handle_udp ( % { state: :failed } = ice_agent , _socket , _src_ip , _src_port , _packet ) do
621+ ice_agent
622+ end
623+
580624 def handle_udp ( ice_agent , socket , src_ip , src_port , packet ) do
581625 turn_tr_id = { socket , { src_ip , src_port } }
582626 turn_tr = Map . get ( ice_agent . gathering_transactions , turn_tr_id )
@@ -588,19 +632,58 @@ defmodule ExICE.Priv.ICEAgent do
588632 handle_turn_gathering_transaction_response ( ice_agent , turn_tr_id , turn_tr , packet )
589633
590634 from_turn? ( ice_agent , src_ip , src_port ) ->
591- handle_turn_message ( ice_agent , socket , src_ip , src_port , packet )
635+ local_cands = Map . values ( ice_agent . local_cands )
636+
637+ case find_relay_cand_by_socket ( local_cands , socket ) do
638+ nil ->
639+ Logger . debug ( """
640+ Couldn't find relay candidate for:
641+ socket: #{ inspect ( socket ) }
642+ src address: #{ inspect ( { src_ip , src_port } ) } .
643+ Ignoring incoming TURN message.
644+ """ )
645+
646+ ice_agent
647+
648+ relay_cand ->
649+ handle_turn_message ( ice_agent , relay_cand , src_ip , src_port , packet )
650+ end
592651
593652 ExSTUN . stun? ( packet ) ->
594- handle_stun_message ( ice_agent , socket , src_ip , src_port , packet )
653+ local_cands = Map . values ( ice_agent . local_cands )
654+
655+ case find_host_cand ( local_cands , socket ) do
656+ nil ->
657+ Logger . debug ( """
658+ Couldn't find host candidate for #{ inspect ( src_ip ) } :#{ src_port } . \
659+ Ignoring incoming STUN message.\
660+ """ )
661+
662+ ice_agent
663+
664+ host_cand ->
665+ handle_stun_message ( ice_agent , host_cand , src_ip , src_port , packet )
666+ end
595667
596668 true ->
597- local_cand = find_host_cand ( Map . values ( ice_agent . local_cands ) , socket )
598- remote_cand = find_remote_cand ( Map . values ( ice_agent . remote_cands ) , src_ip , src_port )
669+ with remote_cands <- Map . values ( ice_agent . remote_cands ) ,
670+ % _ { } = local_cand <- find_host_cand ( Map . values ( ice_agent . local_cands ) , socket ) ,
671+ % _ { } = remote_cand <- find_remote_cand ( remote_cands , src_ip , src_port ) do
672+ % CandidatePair { } =
673+ pair = Checklist . find_pair ( ice_agent . checklist , local_cand . base . id , remote_cand . id )
599674
600- % CandidatePair { } =
601- pair = Checklist . find_pair ( ice_agent . checklist , local_cand . base . id , remote_cand . id )
675+ handle_data_message ( ice_agent , pair , packet )
676+ else
677+ _ ->
678+ Logger . debug ( """
679+ Couldn't find host or remote candidate for:
680+ socket: #{ inspect ( socket ) }
681+ src address: #{ inspect ( { src_ip , src_port } ) } .
682+ Ignoring incoming data message.
683+ """ )
602684
603- handle_data_message ( ice_agent , pair , packet )
685+ ice_agent
686+ end
604687 end
605688 end
606689
@@ -900,9 +983,7 @@ defmodule ExICE.Priv.ICEAgent do
900983 end
901984 end
902985
903- defp handle_turn_message ( ice_agent , socket , src_ip , src_port , packet ) do
904- % cand_mod { } = cand = find_relay_cand_by_socket ( Map . values ( ice_agent . local_cands ) , socket )
905-
986+ defp handle_turn_message ( ice_agent , % cand_mod { } = cand , src_ip , src_port , packet ) do
906987 case cand_mod . receive_data ( cand , src_ip , src_port , packet ) do
907988 { :ok , cand } ->
908989 put_in ( ice_agent . local_cands [ cand . base . id ] , cand )
@@ -935,23 +1016,10 @@ defmodule ExICE.Priv.ICEAgent do
9351016 end
9361017 end
9371018
938- defp handle_stun_message ( ice_agent , socket , src_ip , src_port , packet ) do
1019+ defp handle_stun_message ( ice_agent , host_cand , src_ip , src_port , packet ) do
9391020 case ExSTUN.Message . decode ( packet ) do
9401021 { :ok , msg } ->
941- local_cands = Map . values ( ice_agent . local_cands )
942-
943- case find_host_cand ( local_cands , socket ) do
944- nil ->
945- Logger . debug ( """
946- Couldn't find host candidate for #{ inspect ( src_ip ) } :#{ src_port } . \
947- Ignoring incoming STUN message.\
948- """ )
949-
950- ice_agent
951-
952- local_cand ->
953- do_handle_stun_message ( ice_agent , local_cand , src_ip , src_port , msg )
954- end
1022+ do_handle_stun_message ( ice_agent , host_cand , src_ip , src_port , msg )
9551023
9561024 { :error , reason } ->
9571025 Logger . warning ( "Couldn't decode stun message: #{ inspect ( reason ) } " )
@@ -1957,7 +2025,38 @@ defmodule ExICE.Priv.ICEAgent do
19572025
19582026 @ doc false
19592027 @ spec change_connection_state ( t ( ) , atom ( ) ) :: t ( )
2028+ def change_connection_state ( ice_agent , :failed ) do
2029+ Enum . each ( ice_agent . sockets , fn socket ->
2030+ :ok = ice_agent . transport_module . close ( socket )
2031+ end )
2032+
2033+ ice_agent =
2034+ % {
2035+ ice_agent
2036+ | sockets: [ ] ,
2037+ gathering_transactions: % { } ,
2038+ selected_pair_id: nil ,
2039+ conn_checks: % { } ,
2040+ checklist: % { } ,
2041+ local_cands: % { } ,
2042+ remote_cands: % { } ,
2043+ local_ufrag: nil ,
2044+ local_pwd: nil ,
2045+ remote_ufrag: nil ,
2046+ remote_pwd: nil ,
2047+ eoc: false ,
2048+ nominating?: { false , nil }
2049+ }
2050+ |> disable_timer ( )
2051+
2052+ do_change_connection_state ( ice_agent , :failed )
2053+ end
2054+
19602055 def change_connection_state ( ice_agent , new_conn_state ) do
2056+ do_change_connection_state ( ice_agent , new_conn_state )
2057+ end
2058+
2059+ defp do_change_connection_state ( ice_agent , new_conn_state ) do
19612060 Logger . debug ( "Connection state change: #{ ice_agent . state } -> #{ new_conn_state } " )
19622061 notify ( ice_agent . on_connection_state_change , { :connection_state_change , new_conn_state } )
19632062 % __MODULE__ { ice_agent | state: new_conn_state }
@@ -2135,6 +2234,8 @@ defmodule ExICE.Priv.ICEAgent do
21352234 % { ice_agent | ta_timer: timer }
21362235 end
21372236
2237+ defp disable_timer ( % { ta_timer: nil } = ice_agent ) , do: ice_agent
2238+
21382239 defp disable_timer ( ice_agent ) do
21392240 Process . cancel_timer ( ice_agent . ta_timer )
21402241
0 commit comments