Skip to content

Commit 5c9212f

Browse files
authored
Don't add pairs with srflx local candidate to the checklist (#52)
1 parent 78b2ed9 commit 5c9212f

File tree

2 files changed

+46
-45
lines changed

2 files changed

+46
-45
lines changed

lib/ex_ice/priv/ice_agent.ex

Lines changed: 10 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ defmodule ExICE.Priv.ICEAgent do
1515
}
1616

1717
alias ExICE.Priv.Attribute.{ICEControlling, ICEControlled, Priority, UseCandidate}
18+
alias ExICE.Priv.Candidate.Srflx
1819

1920
alias ExSTUN.Message
2021
alias ExSTUN.Message.Type
@@ -725,20 +726,19 @@ defmodule ExICE.Priv.ICEAgent do
725726

726727
checklist_foundations = get_foundations(ice_agent)
727728

729+
# See RFC 8445 sec. 6.1.2.4
730+
# "For each pair where the local candidate is reflexive, the candidate
731+
# MUST be replaced by its base."
732+
# I belive that this is the same as filtering srflx candidates out.
733+
# Libnice seems to do the same.
728734
new_pairs =
729-
for local_cand <- local_cands, into: %{} do
730-
local_cand =
731-
if local_cand.base.type == :srflx do
732-
local_cand = put_in(local_cand.base.address, local_cand.base.base_address)
733-
put_in(local_cand.base.port, local_cand.base.base_port)
734-
else
735-
local_cand
736-
end
737-
735+
local_cands
736+
|> Enum.reject(fn %mod{} -> mod == Srflx end)
737+
|> Map.new(fn local_cand ->
738738
pair_state = get_pair_state(local_cand, remote_cand, checklist_foundations)
739739
pair = CandidatePair.new(local_cand, remote_cand, ice_agent.role, pair_state)
740740
{pair.id, pair}
741-
end
741+
end)
742742

743743
checklist = Checklist.prune(Map.merge(ice_agent.checklist, new_pairs))
744744

@@ -1489,41 +1489,6 @@ defmodule ExICE.Priv.ICEAgent do
14891489
{conn_check_pair.id, ice_agent}
14901490
end
14911491

1492-
defp add_valid_pair(
1493-
ice_agent,
1494-
valid_pair,
1495-
conn_check_pair,
1496-
%CandidatePair{valid?: true} = checklist_pair
1497-
)
1498-
when are_pairs_equal(valid_pair, checklist_pair) do
1499-
Logger.debug("""
1500-
New valid pair: #{checklist_pair.id} \
1501-
resulted from conn check on pair: #{conn_check_pair.id} \
1502-
but there is already such a pair in the checklist marked as valid.
1503-
Should this ever happen after we don't add redundant srflx candidates?
1504-
Checklist pair: #{checklist_pair.id}.
1505-
""")
1506-
1507-
# if we get here, don't update discovered_pair_id and succeeded_pair_id of
1508-
# the checklist pair as they are already set
1509-
conn_check_pair = %CandidatePair{
1510-
conn_check_pair
1511-
| state: :succeeded,
1512-
succeeded_pair_id: conn_check_pair.id,
1513-
discovered_pair_id: checklist_pair.id
1514-
}
1515-
1516-
checklist_pair = %CandidatePair{checklist_pair | state: :succeeded}
1517-
1518-
checklist =
1519-
ice_agent.checklist
1520-
|> Map.replace!(checklist_pair.id, checklist_pair)
1521-
|> Map.replace!(conn_check_pair.id, conn_check_pair)
1522-
1523-
ice_agent = %__MODULE__{ice_agent | checklist: checklist}
1524-
{checklist_pair.id, ice_agent}
1525-
end
1526-
15271492
defp add_valid_pair(ice_agent, valid_pair, conn_check_pair, checklist_pair)
15281493
when are_pairs_equal(valid_pair, checklist_pair) do
15291494
Logger.debug("""

test/priv/ice_agent_test.exs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,42 @@ defmodule ExICE.Priv.ICEAgentTest do
114114
end
115115
end
116116

117+
test "don't add pairs with srflx local candidate to the checklist" do
118+
ice_agent =
119+
ICEAgent.new(
120+
controlling_process: self(),
121+
role: :controlling,
122+
transport_module: Transport.Mock,
123+
if_discovery_module: IfDiscovery.Mock
124+
)
125+
|> ICEAgent.set_remote_credentials("someufrag", "somepwd")
126+
|> ICEAgent.gather_candidates()
127+
128+
[socket] = ice_agent.sockets
129+
[host_cand] = Map.values(ice_agent.local_cands)
130+
131+
srflx_cand =
132+
ExICE.Priv.Candidate.Srflx.new(
133+
address: {192, 168, 0, 2},
134+
port: 1234,
135+
base_address: host_cand.base.base_address,
136+
base_port: host_cand.base.base_port,
137+
transport_module: ice_agent.transport_module,
138+
socket: socket
139+
)
140+
141+
local_cands = %{host_cand.base.id => host_cand, srflx_cand.base.id => srflx_cand}
142+
ice_agent = %{ice_agent | local_cands: local_cands}
143+
144+
remote_cand = ExICE.Candidate.new(:host, address: {192, 168, 0, 3}, port: 8445)
145+
146+
ice_agent = ICEAgent.add_remote_candidate(ice_agent, remote_cand)
147+
148+
# assert there is only one pair with host local candidate
149+
assert [pair] = Map.values(ice_agent.checklist)
150+
assert pair.local_cand_id == host_cand.base.id
151+
end
152+
117153
describe "sends keepalives" do
118154
setup do
119155
remote_cand = ExICE.Candidate.new(:host, address: {192, 168, 0, 2}, port: 8445)

0 commit comments

Comments
 (0)