Skip to content

Commit

Permalink
Create channel
Browse files Browse the repository at this point in the history
  • Loading branch information
mickel8 committed Apr 13, 2024
1 parent a6f5186 commit 8a86023
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 30 deletions.
63 changes: 43 additions & 20 deletions lib/ex_ice/priv/candidate/relay.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,44 @@ defmodule ExICE.Priv.Candidate.Relay do

@impl true
def send_data(cand, dst_ip, dst_port, data) do
if MapSet.member?(cand.client.permissions, dst_ip) do
{:send, turn_addr, data, client} = ExTURN.Client.send(cand.client, {dst_ip, dst_port}, data)
cand = %{cand | client: client}
do_send(cand, turn_addr, data)
else
{:send, turn_addr, turn_data, client} = ExTURN.Client.create_permission(cand.client, dst_ip)

cand = %{
cand
| client: client,
buffered_packets: [{dst_ip, dst_port, data} | cand.buffered_packets]
}

do_send(cand, turn_addr, turn_data)
permission = MapSet.member?(cand.client.permissions, dst_ip)
channel = Map.has_key?(cand.client.addr_channel, {dst_ip, dst_port})

case {permission, channel} do
{true, true} ->
{:send, turn_addr, data, client} =
ExTURN.Client.send(cand.client, {dst_ip, dst_port}, data)

cand = %{cand | client: client}
do_send(cand, turn_addr, data)

{true, false} ->
{:send, turn_addr, data, client} =
ExTURN.Client.send(cand.client, {dst_ip, dst_port}, data)

cand = %{cand | client: client}

case ExTURN.Client.create_channel(cand.client, dst_ip, dst_port) do
{:ok, client} ->
cand = %{cand | client: client}
do_send(cand, turn_addr, data)

{:send, ^turn_addr, channel_data, client} ->
cand = %{cand | client: client}

with {:ok, cand} <- do_send(cand, turn_addr, data) do
do_send(cand, turn_addr, channel_data)
end
end

{false, false} ->
{:send, turn_addr, turn_data, client} =
ExTURN.Client.create_permission(cand.client, dst_ip)

buffered_data = [{dst_ip, dst_port, data} | cand.buffered_packets]
cand = %{cand | client: client, buffered_packets: buffered_data}

do_send(cand, turn_addr, turn_data)
end
end

Expand Down Expand Up @@ -79,13 +103,12 @@ defmodule ExICE.Priv.Candidate.Relay do
defp do_send_buffered_packets(cand, []), do: {:ok, cand}

defp do_send_buffered_packets(cand, [{dst_ip, dst_port, packet} | packets]) do
{:send, turn_addr, data, client} = ExTURN.Client.send(cand.client, {dst_ip, dst_port}, packet)

cand = %{cand | client: client}
case send_data(cand, dst_ip, dst_port, packet) do
{:ok, cand} ->
do_send_buffered_packets(cand, packets)

case do_send(cand, turn_addr, data) do
{:ok, cand} -> do_send_buffered_packets(cand, packets)
{:error, _reason, _cand} = error -> error
{:error, _reaons, _cand} = error ->
error
end
end

Expand Down
3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ defmodule ExICE.MixProject do
[
# {:ex_stun, "~> 0.1.0"},
{:ex_stun, github: "elixir-webrtc/ex_stun"},
{:ex_turn, github: "elixir-webrtc/ex_turn"},
# {:ex_turn, github: "elixir-webrtc/ex_turn"},
{:ex_turn, github: "elixir-webrtc/ex_turn", branch: "channel-bind"},
{:excoveralls, "~> 0.15", only: :test, runtime: false},
{:ex_doc, "~> 0.27", only: :dev, runtime: false},
{:credo, "~> 1.6", only: [:dev, :test], runtime: false},
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ex_doc": {:hex, :ex_doc, "0.31.2", "8b06d0a5ac69e1a54df35519c951f1f44a7b7ca9a5bb7a260cd8a174d6322ece", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "317346c14febaba9ca40fd97b5b5919f7751fb85d399cc8e7e8872049f37e0af"},
"ex_stun": {:git, "https://github.com/elixir-webrtc/ex_stun.git", "5d1243a6c3268d0cb402c6272ae6e0df1615779a", []},
"ex_turn": {:git, "https://github.com/elixir-webrtc/ex_turn.git", "14df4a546f2e19a85731eef70258c490a71e856d", []},
"ex_turn": {:git, "https://github.com/elixir-webrtc/ex_turn.git", "3411d8f2271c60eab901dd551ce4a6ef5d91dda3", [branch: "channel-bind"]},
"excoveralls": {:hex, :excoveralls, "0.18.1", "a6f547570c6b24ec13f122a5634833a063aec49218f6fff27de9df693a15588c", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d65f79db146bb20399f23046015974de0079668b9abb2f5aac074d078da60b8d"},
"file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
Expand Down
2 changes: 1 addition & 1 deletion test/priv/gatherer_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ defmodule ExICE.Priv.GathererTest do
[%Candidate.Host{} = c] = Gatherer.gather_host_candidates(gatherer, sockets)

assert :ok = Gatherer.gather_srflx_candidate(gatherer, 1234, c.base.socket, stun_server)
assert [{_socket, packet}] = :ets.lookup(:transport_mock, c.base.socket)
assert packet = Transport.Mock.recv(c.base.socket)
assert {:ok, req} = ExSTUN.Message.decode(packet)
assert req.attributes == []
assert req.type == %Type{class: :request, method: :binding}
Expand Down
31 changes: 29 additions & 2 deletions test/priv/ice_agent_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ defmodule ExICE.Priv.ICEAgentTest do

ice_agent = ICEAgent.handle_udp(ice_agent, socket, @turn_ip, @turn_port, resp)

# assert client sends binding request
# assert client sends ice binding request and channel bind request
assert packet = Transport.Mock.recv(socket)
assert {:ok, req} = ExSTUN.Message.decode(packet)
assert req.type.class == :indication
Expand All @@ -988,6 +988,11 @@ defmodule ExICE.Priv.ICEAgentTest do
assert req.type.class == :request
assert req.type.method == :binding

assert packet = Transport.Mock.recv(socket)
assert {:ok, channel_req} = ExSTUN.Message.decode(packet)
assert channel_req.type.class == :request
assert channel_req.type.method == :channel_bind

# send binding success response
resp =
Message.new(req.transaction_id, %Type{class: :success_response, method: :binding}, [
Expand Down Expand Up @@ -1028,10 +1033,32 @@ defmodule ExICE.Priv.ICEAgentTest do
])
|> Message.encode()

_ice_agent = ICEAgent.handle_udp(ice_agent, socket, @turn_ip, @turn_port, indication)
ice_agent = ICEAgent.handle_udp(ice_agent, socket, @turn_ip, @turn_port, indication)
assert_receive {:ex_ice, _pid, {:data, "someremotedata"}}

# send channel bind success response
channel_resp =
Message.new(
channel_req.transaction_id,
%Type{class: :success_response, method: :channel_bind},
[]
)
|> Message.with_integrity(Message.lt_key(@turn_username, @turn_password, @turn_realm))
|> Message.encode()

ice_agent = ICEAgent.handle_udp(ice_agent, socket, @turn_ip, @turn_port, channel_resp)

# try to once again send some data, this time it should be sent over channel
_ice_agent = ICEAgent.send_data(ice_agent, "somedata")
assert packet = Transport.Mock.recv(socket)
assert nil == Transport.Mock.recv(socket)
assert channel_data?(packet)
assert <<_channel_number::16, _len::16, "somedata">> = packet
end

defp channel_data?(<<1::2, _rest::bitstring>>), do: true
defp channel_data?(_), do: false

defp binding_response(t_id, transport_module, socket, remote_pwd) do
{:ok, {sock_ip, sock_port}} = transport_module.sockname(socket)

Expand Down
17 changes: 12 additions & 5 deletions test/support/transport/mock.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,14 @@ defmodule ExICE.Support.Transport.Mock do

@spec recv(ExICE.Transport.socket()) :: binary() | nil
def recv(socket) do
[{_socket, packet}] = :ets.lookup(:transport_mock, socket)
packet
case :ets.lookup(:transport_mock, socket) do
[{_socket, []}] ->
nil

[{_socket, [head | tail]}] ->
:ets.insert(:transport_mock, {socket, tail})
head
end
end

@impl true
Expand Down Expand Up @@ -57,7 +63,7 @@ defmodule ExICE.Support.Transport.Mock do
port ->
socket = %{port: port, ip: ip}

unless :ets.insert_new(:transport_mock, {socket, nil}) do
unless :ets.insert_new(:transport_mock, {socket, []}) do
raise "Couldn't open socket: #{inspect(socket)}, reason: eaddrinuse."
end

Expand All @@ -72,7 +78,8 @@ defmodule ExICE.Support.Transport.Mock do

@impl true
def send(socket, _dst, packet) do
:ets.insert(:transport_mock, {socket, packet})
[{_socket, buffer}] = :ets.lookup(:transport_mock, socket)
:ets.insert(:transport_mock, {socket, buffer ++ [packet]})
:ok
end

Expand All @@ -86,7 +93,7 @@ defmodule ExICE.Support.Transport.Mock do
Enum.find_value(49_152..65_535, fn port ->
socket = %{ip: ip, port: port}

if :ets.insert_new(:transport_mock, {socket, nil}) do
if :ets.insert_new(:transport_mock, {socket, []}) do
socket
else
false
Expand Down

0 comments on commit 8a86023

Please sign in to comment.