@@ -842,23 +842,51 @@ defmodule ExICE.ICEAgent do
842
842
defp handle_gathering_transaction_success_response ( _socket , _src_ip , _src_port , msg , state ) do
843
843
t = Map . fetch! ( state . gathering_transactions , msg . transaction_id )
844
844
845
- { :ok , % XORMappedAddress { address: address , port: port } } =
845
+ { :ok , % XORMappedAddress { address: xor_addr , port: xor_port } } =
846
846
Message . get_attribute ( msg , XORMappedAddress )
847
847
848
- c =
849
- Candidate . new (
850
- :srflx ,
851
- address ,
852
- port ,
853
- t . host_cand . address ,
854
- t . host_cand . port ,
855
- t . host_cand . socket
856
- )
848
+ case find_cand ( state . local_cands , xor_addr , xor_port ) do
849
+ nil ->
850
+ c =
851
+ Candidate . new (
852
+ :srflx ,
853
+ xor_addr ,
854
+ xor_port ,
855
+ t . host_cand . address ,
856
+ t . host_cand . port ,
857
+ t . host_cand . socket
858
+ )
859
+
860
+ Logger . debug ( "New srflx candidate: #{ inspect ( c ) } " )
861
+ send ( state . controlling_process , { :ex_ice , self ( ) , { :new_candidate , Candidate . marshal ( c ) } } )
862
+ add_srflx_cand ( c , state )
863
+
864
+ cand ->
865
+ Logger . debug ( """
866
+ Not adding srflx candidate as we already have a candidate with the same address.
867
+ Candidate: #{ inspect ( cand ) }
868
+ """ )
869
+ end
870
+ |> update_in ( [ :gathering_transactions , t . t_id ] , fn t -> % { t | state: :complete } end )
871
+ end
857
872
858
- Logger . debug ( "New srflx candidate: #{ inspect ( c ) } " )
873
+ defp handle_gathering_transaction_error_response ( _socket , _src_ip , _src_port , msg , state ) do
874
+ t = Map . fetch! ( state . gathering_transactions , msg . transaction_id )
859
875
860
- send ( state . controlling_process , { :ex_ice , self ( ) , { :new_candidate , Candidate . marshal ( c ) } } )
876
+ error_code =
877
+ case Message . get_attribute ( msg , ErrorCode ) do
878
+ { :ok , error_code } -> error_code
879
+ _other -> nil
880
+ end
881
+
882
+ Logger . debug (
883
+ "Gathering transaction failed, t_id: #{ msg . transaction_id } , reason: #{ inspect ( error_code ) } "
884
+ )
885
+
886
+ update_in ( state , [ :gathering_transactions , t . t_id ] , fn t -> % { t | state: :failed } end )
887
+ end
861
888
889
+ defp add_srflx_cand ( c , state ) do
862
890
# replace address and port with candidate base
863
891
# and prune the checklist - see sec. 6.1.2.4
864
892
local_cand = % Candidate { c | address: c . base_address , port: c . base_port }
@@ -884,56 +912,15 @@ defmodule ExICE.ICEAgent do
884
912
Logger . debug ( "New candidate pairs: #{ inspect ( added_pairs ) } " )
885
913
end
886
914
887
- state
888
- |> update_in ( [ :local_cands ] , fn local_cands -> [ c | local_cands ] end )
889
- |> update_in ( [ :gathering_transactions , t . t_id ] , fn t -> % { t | state: :complete } end )
890
- |> update_in ( [ :checklist ] , fn _ -> checklist end )
891
- end
892
-
893
- defp handle_gathering_transaction_error_response ( _socket , _src_ip , _src_port , msg , state ) do
894
- t = Map . fetch! ( state . gathering_transactions , msg . transaction_id )
895
-
896
- error_code =
897
- case Message . get_attribute ( msg , ErrorCode ) do
898
- { :ok , error_code } -> error_code
899
- _other -> nil
900
- end
901
-
902
- Logger . debug (
903
- "Gathering transaction failed, t_id: #{ msg . transaction_id } , reason: #{ inspect ( error_code ) } "
904
- )
905
-
906
- update_in ( state , [ :gathering_transactions , t . t_id ] , fn t -> % { t | state: :failed } end )
915
+ % { state | checklist: checklist , local_cands: [ c | state . local_cands ] }
907
916
end
908
917
909
918
# Adds valid pair according to sec 7.2.5.3.2
910
919
# TODO sec. 7.2.5.3.3
911
920
# The agent MUST set the states for all other Frozen candidate pairs in
912
921
# all checklists with the same foundation to Waiting.
913
- defp add_valid_pair (
914
- valid_pair ,
915
- conn_check_pair ,
916
- % CandidatePair { valid?: true } = checklist_pair ,
917
- % { role: :controlling } = state
918
- )
919
- when are_pairs_equal ( valid_pair , checklist_pair ) do
920
- # valid pair is already in the checklist and it is
921
- # marked as valid so this cannot be our first conn check on it -
922
- # this means that nominate? flag has to be set
923
- true = checklist_pair . nominate?
924
- conn_check_pair = % CandidatePair { conn_check_pair | state: :succeeded }
925
- checklist_pair = % CandidatePair { checklist_pair | state: :succeeded }
926
-
927
- checklist =
928
- state . checklist
929
- |> Map . replace! ( checklist_pair . id , checklist_pair )
930
- |> Map . replace! ( conn_check_pair . id , conn_check_pair )
931
-
932
- state = % { state | checklist: checklist }
933
- { checklist_pair . id , state }
934
- end
935
-
936
- # check against valid_pair == conn_check_pair before
922
+ #
923
+ # Check against valid_pair == conn_check_pair before
937
924
# checking against valid_pair == checklist_pair as
938
925
# the second condition is always true if the first one is
939
926
defp add_valid_pair ( valid_pair , conn_check_pair , _ , state )
@@ -957,6 +944,41 @@ defmodule ExICE.ICEAgent do
957
944
{ conn_check_pair . id , state }
958
945
end
959
946
947
+ defp add_valid_pair (
948
+ valid_pair ,
949
+ conn_check_pair ,
950
+ % CandidatePair { valid?: true } = checklist_pair ,
951
+ state
952
+ )
953
+ when are_pairs_equal ( valid_pair , checklist_pair ) do
954
+ Logger . debug ( """
955
+ New valid pair: #{ checklist_pair . id } \
956
+ resulted from conn check on pair: #{ conn_check_pair . id } \
957
+ but there is already such a pair in the checklist marked as valid.
958
+ Should this ever happen after we don't add redundant srflx candidates?
959
+ Checklist pair: #{ checklist_pair . id } .
960
+ """ )
961
+
962
+ # if we get here, don't update discovered_pair_id and succeeded_pair_id of
963
+ # the checklist pair as they are already set
964
+ conn_check_pair = % CandidatePair {
965
+ conn_check_pair
966
+ | state: :succeeded ,
967
+ succeeded_pair_id: conn_check_pair . id ,
968
+ discovered_pair_id: checklist_pair . id
969
+ }
970
+
971
+ checklist_pair = % CandidatePair { checklist_pair | state: :succeeded }
972
+
973
+ checklist =
974
+ state . checklist
975
+ |> Map . replace! ( checklist_pair . id , checklist_pair )
976
+ |> Map . replace! ( conn_check_pair . id , conn_check_pair )
977
+
978
+ state = % { state | checklist: checklist }
979
+ { checklist_pair . id , state }
980
+ end
981
+
960
982
defp add_valid_pair ( valid_pair , conn_check_pair , checklist_pair , state )
961
983
when are_pairs_equal ( valid_pair , checklist_pair ) do
962
984
Logger . debug ( """
@@ -1150,7 +1172,7 @@ defmodule ExICE.ICEAgent do
1150
1172
% CandidatePair { } = pair ->
1151
1173
Logger . debug ( "Trying to nominate pair: #{ inspect ( pair . id ) } " )
1152
1174
pair = % CandidatePair { pair | nominate?: true }
1153
- put_in ( state , [ :checklist , pair . id ] , pair )
1175
+ state = put_in ( state , [ :checklist , pair . id ] , pair )
1154
1176
state = % { state | nominating?: { true , pair . id } }
1155
1177
pair = Map . fetch! ( state . checklist , pair . succeeded_pair_id )
1156
1178
pair = % CandidatePair { pair | state: :waiting , nominate?: true }
@@ -1160,7 +1182,10 @@ defmodule ExICE.ICEAgent do
1160
1182
nil ->
1161
1183
# TODO revisit this
1162
1184
# should we check if state.state == :in_progress?
1163
- Logger . debug ( "No pairs for nomination. ICE failed." )
1185
+ Logger . debug ( """
1186
+ No pairs for nomination. ICE failed. #{ inspect ( state . checklist , pretty: true ) }
1187
+ """ )
1188
+
1164
1189
change_connection_state ( :failed , state )
1165
1190
end
1166
1191
end
0 commit comments