Skip to content

Commit 00b3506

Browse files
committed
Make distinction between valid and succeeded pair
1 parent 7c93c4d commit 00b3506

File tree

4 files changed

+107
-64
lines changed

4 files changed

+107
-64
lines changed

lib/candidate_pair.ex

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ defmodule ExICE.CandidatePair do
1717
priority: non_neg_integer(),
1818
remote_cand: Candidate.t(),
1919
state: state(),
20-
valid?: boolean
20+
valid?: boolean,
21+
succeeded_pair_id: integer() | nil,
22+
discovered_pair_id: integer() | nil
2123
}
2224

2325
@enforce_keys [:id, :local_cand, :remote_cand, :priority]
@@ -26,7 +28,9 @@ defmodule ExICE.CandidatePair do
2628
nominate?: false,
2729
nominated?: false,
2830
state: :frozen,
29-
valid?: false
31+
valid?: false,
32+
succeeded_pair_id: nil,
33+
discovered_pair_id: nil
3034
]
3135

3236
@doc false

lib/controlled_handler.ex

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ defmodule ExICE.ControlledHandler do
1818
Logger.debug("Adding new candidate pair: #{inspect(pair)}")
1919
put_in(state, [:checklist, pair.id], pair)
2020

21-
%CandidatePair{} = pair when pair == state.selected_pair ->
21+
%CandidatePair{} = pair
22+
when state.selected_pair != nil and pair.discovered_pair_id == state.selected_pair.id ->
2223
# to be honest this might also be a retransmission
23-
Logger.debug("Keepalive on selected pair: #{pair.id}")
24+
Logger.debug("Keepalive on selected pair: #{pair.discovered_pair_id}")
2425
state
2526

2627
%CandidatePair{} ->
@@ -44,19 +45,16 @@ defmodule ExICE.ControlledHandler do
4445
pair = %CandidatePair{pair | nominate?: true}
4546
put_in(state, [:checklist, pair.id], pair)
4647

47-
%CandidatePair{} = pair when pair == state.selected_pair ->
48+
%CandidatePair{} = pair
49+
when state.selected_pair != nil and pair.discovered_pair_id == state.selected_pair.id ->
4850
Logger.debug("Keepalive on selected pair: #{pair.id}")
4951
state
5052

5153
%CandidatePair{} = pair ->
5254
if pair.state == :succeeded do
53-
# FIXME we should check against valid? flag
54-
# it's possible to have to pairs: one with state succeeded
55-
# and flag valid? set to false, and the other one with state
56-
# succeeded and flag valid? set to true
5755
# TODO should we call this selected or nominated pair
58-
Logger.debug("Nomination request on valid pair: #{pair.id}.")
59-
update_nominated_flag(state, pair.id, true)
56+
Logger.debug("Nomination request on pair: #{pair.id}.")
57+
update_nominated_flag(state, pair.discovered_pair_id, true)
6058
else
6159
# TODO should we check if this pair is not in failed?
6260
Logger.debug("""
@@ -79,31 +77,32 @@ defmodule ExICE.ControlledHandler do
7977
Logger.debug("Nomination succeeded, pair: #{pair_id}")
8078

8179
pair = Map.fetch!(state.checklist, pair_id)
80+
succeeded_pair = Map.fetch!(state.checklist, pair.succeeded_pair_id)
8281

83-
state =
84-
cond do
85-
state.selected_pair == nil ->
86-
Logger.debug("Selecting pair: #{pair_id}")
87-
%{state | selected_pair: pair}
82+
pair = %CandidatePair{pair | nominate?: false, nominated?: true}
83+
succeeded_pair = %CandidatePair{succeeded_pair | nominate?: false}
8884

89-
state.selected_pair != nil and pair.priority >= state.selected_pair.priority ->
90-
Logger.debug("""
91-
Selecting new pair with higher priority. \
92-
New pair: #{pair_id}, old pair: #{state.selected_pair.id}.\
93-
""")
85+
state =
86+
state
87+
|> put_in([:checklist, pair.id], pair)
88+
|> put_in([:checklist, succeeded_pair.id], succeeded_pair)
9489

95-
%{state | selected_pair: pair}
90+
cond do
91+
state.selected_pair == nil ->
92+
Logger.debug("Selecting pair: #{pair_id}")
93+
%{state | selected_pair: pair}
9694

97-
true ->
98-
Logger.debug("Not selecting a new pair as it has lower priority")
99-
state
100-
end
95+
state.selected_pair != nil and pair.priority >= state.selected_pair.priority ->
96+
Logger.debug("""
97+
Selecting new pair with higher priority. \
98+
New pair: #{pair_id}, old pair: #{state.selected_pair.id}.\
99+
""")
101100

102-
checklist =
103-
Map.update!(state.checklist, pair_id, fn pair ->
104-
%CandidatePair{pair | nominate?: false, nominated?: true}
105-
end)
101+
%{state | selected_pair: pair}
106102

107-
%{state | checklist: checklist, selected_pair: Map.fetch!(checklist, pair_id)}
103+
true ->
104+
Logger.debug("Not selecting a new pair as it has lower priority")
105+
state
106+
end
108107
end
109108
end

lib/controlling_handler.ex

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ defmodule ExICE.ControllingHandler do
2929
Logger.debug("Adding new candidate pair: #{inspect(pair)}")
3030
put_in(state, [:checklist, pair.id], pair)
3131

32-
%CandidatePair{} = pair when pair == state.selected_pair ->
32+
%CandidatePair{} = pair
33+
when state.selected_pair != nil and pair.discovered_pair_id == state.selected_pair.id ->
3334
# to be honest this might also be a retransmission
34-
Logger.debug("Keepalive on selected pair: #{pair.id}")
35+
Logger.debug("Keepalive on selected pair: #{pair.discovered_pair_id}")
3536
state
3637

3738
%CandidatePair{} ->
@@ -48,21 +49,21 @@ defmodule ExICE.ControllingHandler do
4849
Logger.debug("Nomination succeeded. Selecting pair: #{inspect(pair_id)}")
4950
state = ICEAgent.change_connection_state(:completed, state)
5051

51-
checklist =
52-
Map.update!(state.checklist, pair_id, fn pair ->
53-
%CandidatePair{pair | nominate?: false, nominated?: true}
54-
end)
52+
pair = Map.fetch!(state.checklist, pair_id)
53+
succeeded_pair = Map.fetch!(state.checklist, pair.succeeded_pair_id)
54+
55+
pair = %CandidatePair{pair | nominate?: false, nominated?: true}
56+
succeeded_pair = %CandidatePair{succeeded_pair | nominate?: false}
57+
58+
state =
59+
state
60+
|> put_in([:checklist, pair.id], pair)
61+
|> put_in([:checklist, succeeded_pair.id], succeeded_pair)
5562

5663
# the controlling agent could nominate only when eoc was set
5764
# and checklist finished
58-
# important: we have to check on a new checklist
59-
false = Checklist.in_progress?(checklist) or Checklist.waiting?(checklist)
65+
false = Checklist.in_progress?(state.checklist) or Checklist.waiting?(state.checklist)
6066

61-
%{
62-
state
63-
| checklist: checklist,
64-
nominating?: {false, nil},
65-
selected_pair: Map.fetch!(checklist, pair_id)
66-
}
67+
%{state | nominating?: {false, nil}, selected_pair: pair}
6768
end
6869
end

lib/ice_agent.ex

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ defmodule ExICE.ICEAgent do
136136
stun_server
137137

138138
:error ->
139-
Logger.warn("""
139+
Logger.warning("""
140140
Couldn't parse STUN server URI: #{inspect(stun_server)}. \
141141
Ignoring.\
142142
""")
@@ -198,7 +198,7 @@ defmodule ExICE.ICEAgent do
198198
{:set_remote_credentials, ufrag, pwd},
199199
%{remote_ufrag: ufrag, remote_pwd: pwd} = state
200200
) do
201-
Logger.warn("Passed the same remote credentials to be set. Ignoring.")
201+
Logger.warning("Passed the same remote credentials to be set. Ignoring.")
202202
{:noreply, state}
203203
end
204204

@@ -212,13 +212,13 @@ defmodule ExICE.ICEAgent do
212212

213213
@impl true
214214
def handle_cast(:gather_candidates, %{gathering_state: :gathering} = state) do
215-
Logger.warn("Can't gather candidates. Gathering already in progress. Ignoring.")
215+
Logger.warning("Can't gather candidates. Gathering already in progress. Ignoring.")
216216
{:noreply, state}
217217
end
218218

219219
@impl true
220220
def handle_cast(:gather_candidates, %{gathering_state: :complete} = state) do
221-
Logger.warn("Can't gather candidates. ICE restart needed. Ignoring.")
221+
Logger.warning("Can't gather candidates. ICE restart needed. Ignoring.")
222222
{:noreply, state}
223223
end
224224

@@ -265,7 +265,7 @@ defmodule ExICE.ICEAgent do
265265

266266
@impl true
267267
def handle_cast({:add_remote_candidate, _remote_cand}, %{eoc: true} = state) do
268-
Logger.warn("Received remote candidate after end-of-candidates. Ignoring.")
268+
Logger.warning("Received remote candidate after end-of-candidates. Ignoring.")
269269
{:noreply, state}
270270
end
271271

@@ -282,7 +282,7 @@ defmodule ExICE.ICEAgent do
282282
{:noreply, state}
283283

284284
{:error, reason} ->
285-
Logger.warn("Invalid remote candidate, reason: #{inspect(reason)}. Ignoring.")
285+
Logger.warning("Invalid remote candidate, reason: #{inspect(reason)}. Ignoring.")
286286
{:noreply, state}
287287
end
288288
end
@@ -320,7 +320,7 @@ defmodule ExICE.ICEAgent do
320320

321321
@impl true
322322
def handle_cast({:send_data, _data}, %{state: ice_state} = state) do
323-
Logger.warn("""
323+
Logger.warning("""
324324
Cannot send data in ICE state: #{inspect(ice_state)}. \
325325
Data can only be sent in state :connected or :completed. Ignoring.\
326326
""")
@@ -347,7 +347,7 @@ defmodule ExICE.ICEAgent do
347347

348348
@impl true
349349
def handle_info(:ta_timeout, state) when state.state in [:completed, :failed] do
350-
Logger.warn("""
350+
Logger.warning("""
351351
Ta timer fired in unexpected state: #{state.state}.
352352
Trying to update gathering and connection states.
353353
""")
@@ -419,7 +419,7 @@ defmodule ExICE.ICEAgent do
419419
{:noreply, state}
420420

421421
{:error, reason} ->
422-
Logger.warn("Couldn't decode stun message: #{inspect(reason)}")
422+
Logger.warning("Couldn't decode stun message: #{inspect(reason)}")
423423
{:noreply, state}
424424
end
425425
else
@@ -430,7 +430,7 @@ defmodule ExICE.ICEAgent do
430430

431431
@impl true
432432
def handle_info(msg, state) do
433-
Logger.warn("Got unexpected msg: #{inspect(msg)}")
433+
Logger.warning("Got unexpected msg: #{inspect(msg)}")
434434
{:noreply, state}
435435
end
436436

@@ -572,15 +572,15 @@ defmodule ExICE.ICEAgent do
572572
handle_gathering_transaction_response(socket, src_ip, src_port, msg, state)
573573

574574
%Type{class: class, method: :binding} when is_response(class) ->
575-
Logger.warn("""
575+
Logger.warning("""
576576
Ignoring binding response with unknown t_id: #{msg.transaction_id}.
577577
Is it retransmission or we called ICE restart?
578578
""")
579579

580580
state
581581

582582
other ->
583-
Logger.warn("""
583+
Logger.warning("""
584584
Unknown msg from: #{inspect({src_ip, src_port})}, on: #{inspect(socket_addr)}, msg: #{inspect(other)} \
585585
""")
586586

@@ -746,7 +746,7 @@ defmodule ExICE.ICEAgent do
746746
else
747747
{:ok, {socket_ip, socket_port}} = :inet.sockname(socket)
748748

749-
Logger.warn("""
749+
Logger.warning("""
750750
Ignoring conn check response, non-symmetric src and dst addresses.
751751
Sent from: #{inspect({conn_check_pair.local_cand.base_address, conn_check_pair.local_cand.base_port})}, \
752752
to: #{inspect({conn_check_pair.remote_cand.address, conn_check_pair.remote_cand.port})}
@@ -906,7 +906,7 @@ defmodule ExICE.ICEAgent do
906906
# all checklists with the same foundation to Waiting.
907907
defp add_valid_pair(
908908
valid_pair,
909-
_conn_check_pair,
909+
conn_check_pair,
910910
%CandidatePair{valid?: true} = checklist_pair,
911911
%{role: :controlling} = state
912912
)
@@ -915,8 +915,14 @@ defmodule ExICE.ICEAgent do
915915
# marked as valid so this cannot be our first conn check on it -
916916
# this means that nominate? flag has to be set
917917
true = checklist_pair.nominate?
918+
conn_check_pair = %CandidatePair{conn_check_pair | state: :succeeded}
918919
checklist_pair = %CandidatePair{checklist_pair | state: :succeeded}
919-
checklist = Map.replace!(state.checklist, checklist_pair.id, checklist_pair)
920+
921+
checklist =
922+
state.checklist
923+
|> Map.replace!(checklist_pair.id, checklist_pair)
924+
|> Map.replace!(conn_check_pair.id, conn_check_pair)
925+
920926
state = %{state | checklist: checklist}
921927
{checklist_pair.id, state}
922928
end
@@ -931,7 +937,13 @@ defmodule ExICE.ICEAgent do
931937
resulted from conn check on pair: #{inspect(conn_check_pair.id)}\
932938
""")
933939

934-
conn_check_pair = %CandidatePair{conn_check_pair | state: :succeeded, valid?: true}
940+
conn_check_pair = %CandidatePair{
941+
conn_check_pair
942+
| succeeded_pair_id: conn_check_pair.id,
943+
discovered_pair_id: conn_check_pair.id,
944+
state: :succeeded,
945+
valid?: true
946+
}
935947

936948
checklist = Map.replace!(state.checklist, conn_check_pair.id, conn_check_pair)
937949

@@ -946,8 +958,20 @@ defmodule ExICE.ICEAgent do
946958
resulted from conn check on pair: #{inspect(conn_check_pair.id)}\
947959
""")
948960

949-
conn_check_pair = %CandidatePair{conn_check_pair | state: :succeeded}
950-
checklist_pair = %CandidatePair{checklist_pair | state: :succeeded, valid?: true}
961+
conn_check_pair = %CandidatePair{
962+
conn_check_pair
963+
| discovered_pair_id: checklist_pair.id,
964+
succeeded_pair_id: conn_check_pair.id,
965+
state: :succeeded
966+
}
967+
968+
checklist_pair = %CandidatePair{
969+
checklist_pair
970+
| discovered_pair_id: checklist_pair.id,
971+
succeeded_pair_id: conn_check_pair.id,
972+
state: :succeeded,
973+
valid?: true
974+
}
951975

952976
checklist =
953977
state.checklist
@@ -967,7 +991,18 @@ defmodule ExICE.ICEAgent do
967991

968992
Logger.debug("New valid pair: #{inspect(valid_pair.id)}")
969993

970-
conn_check_pair = %CandidatePair{conn_check_pair | state: :succeeded}
994+
conn_check_pair = %CandidatePair{
995+
conn_check_pair
996+
| discovered_pair_id: valid_pair.id,
997+
succeeded_pair_id: conn_check_pair.id,
998+
state: :succeeded
999+
}
1000+
1001+
valid_pair = %CandidatePair{
1002+
valid_pair
1003+
| discovered_pair_id: valid_pair.id,
1004+
succeeded_pair_id: conn_check_pair.id
1005+
}
9711006

9721007
checklist =
9731008
state.checklist
@@ -1108,6 +1143,10 @@ defmodule ExICE.ICEAgent do
11081143
case Checklist.get_pair_for_nomination(state.checklist) do
11091144
%CandidatePair{} = pair ->
11101145
Logger.debug("Trying to nominate pair: #{inspect(pair.id)}")
1146+
pair = %CandidatePair{pair | nominate?: true}
1147+
put_in(state, [:checklist, pair.id], pair)
1148+
state = %{state | nominating?: {true, pair.id}}
1149+
pair = Map.fetch!(state.checklist, pair.succeeded_pair_id)
11111150
pair = %CandidatePair{pair | state: :waiting, nominate?: true}
11121151
{pair, state} = send_conn_check(pair, state)
11131152
put_in(state, [:checklist, pair.id], pair)

0 commit comments

Comments
 (0)