Skip to content

Commit

Permalink
Add support for STUN/TURN FQDN addresses (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
mickel8 authored Mar 16, 2021
1 parent fe57227 commit 856ebd3
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 34 deletions.
77 changes: 55 additions & 22 deletions lib/ex_libnice.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,19 @@ defmodule ExLibnice do
stream_components: %{}
end

@typedoc """
Fully qualified domain name e.g. "my.domain.com".
"""
@type fqdn() :: String.t()

@type stun_server() :: %{server_addr: :inet.ip_address() | fqdn(), server_port: 0..65_535}

@typedoc """
Type describing TURN server configuration
"""
@type relay_info :: %{
server_ip: :inet.ip_address(),
server_port: integer(),
server_addr: :inet.ip_address() | fqdn(),
server_port: 0..65_535,
username: String.t(),
password: String.t(),
relay_type: :udp | :tcp | :tls
Expand All @@ -48,7 +55,7 @@ defmodule ExLibnice do
"""
@type opts_t :: [
parent: pid(),
stun_servers: [String.t()],
stun_servers: [stun_server()],
controlling_mode: boolean(),
port_range: 0..65_535
]
Expand Down Expand Up @@ -90,7 +97,10 @@ defmodule ExLibnice do
stream_id :: integer(),
component_id :: integer() | [integer()] | :all,
relay_info :: relay_info() | [relay_info()]
) :: :ok | {:error, :bad_stream_id | :bad_relay_type | :failed_to_set_turn}
) ::
:ok
| {:error,
:bad_stream_id | :bad_relay_type | :failed_to_resolve_addr | :failed_to_set_turn}
def set_relay_info(pid, stream_id, component_id, relay_info) do
GenServer.call(pid, {:set_relay_info, stream_id, component_id, relay_info})
end
Expand Down Expand Up @@ -236,9 +246,11 @@ defmodule ExLibnice do

{:ok, cnode} = Unifex.CNode.start_link(:native)

{:ok, stun_servers} = lookup_stun_servers(opts[:stun_servers])

:ok =
Unifex.CNode.call(cnode, :init, [
opts[:stun_servers],
stun_servers,
opts[:controlling_mode],
min_port,
max_port
Expand Down Expand Up @@ -509,6 +521,15 @@ defmodule ExLibnice do
{:noreply, state}
end

defp lookup_stun_servers(stun_servers) do
Bunch.Enum.try_map(stun_servers, fn %{server_addr: addr, server_port: port} ->
case lookup_addr(addr) do
{:ok, ip} -> {:ok, "#{:inet.ntoa(ip)}:#{port}"}
{:error, _cause} = error -> error
end
end)
end

defp do_set_relay_info(state, stream_id, components, relay_info) when is_list(components),
do: Bunch.Enum.try_each(components, &do_set_relay_info(state, stream_id, &1, relay_info))

Expand All @@ -528,44 +549,56 @@ defmodule ExLibnice do
_state,
stream_id,
component_id,
%{server_ip: server_ip, server_port: server_port, relay_type: relay_type}
%{server_addr: server_addr, server_port: server_port, relay_type: relay_type}
)
when relay_type not in [:udp, :tcp, :tls] do
Logger.warn("""
Couldn't set TURN server #{inspect(server_ip)} #{inspect(server_port)} #{inspect(relay_type)} \
for component: #{inspect(component_id)} in stream: #{inspect(stream_id)}, cause: bad_relay_type
Couldn't set TURN server #{inspect(server_addr)} #{inspect(server_port)} \
#{inspect(relay_type)} for component: #{inspect(component_id)} in stream: \
#{inspect(stream_id)}, cause: bad_relay_type
""")

{:error, :bad_relay_type}
end

defp do_set_relay_info(%{cnode: cnode}, stream_id, component_id, %{
server_ip: server_ip,
server_addr: server_addr,
server_port: server_port,
username: username,
password: password,
relay_type: relay_type
}) do
case Unifex.CNode.call(cnode, :set_relay_info, [
stream_id,
component_id,
:inet.ntoa(server_ip) |> to_string(),
server_port,
username,
password,
Atom.to_string(relay_type)
]) do
:ok ->
:ok

with {:ok, server_ip} <- lookup_addr(server_addr),
:ok <-
Unifex.CNode.call(cnode, :set_relay_info, [
stream_id,
component_id,
:inet.ntoa(server_ip) |> to_string(),
server_port,
username,
password,
Atom.to_string(relay_type)
]) do
:ok
else
{:error, cause} = error ->
Logger.warn("""
Couldn't set TURN server #{inspect(server_ip)} #{inspect(server_port)} \
Couldn't set TURN server #{inspect(server_addr)} #{inspect(server_port)} \
#{inspect(relay_type)} for component: #{inspect(component_id)} in stream: \
#{inspect(stream_id)}, cause: #{inspect(cause)}
""")

error
end
end

defp lookup_addr({_a, _b, _c, _d} = addr), do: {:ok, addr}
defp lookup_addr({_a, _b, _c, _d, _e, _f, _g, _h} = addr), do: {:ok, addr}

defp lookup_addr(addr) when is_binary(addr) do
case :inet_res.lookup(to_charlist(addr), :in, :a) do
[] -> {:error, :failed_to_lookup_address}
[h | _t] -> {:ok, h}
end
end
end
6 changes: 3 additions & 3 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
"bundlex": {:hex, :bundlex, "0.4.1", "4bf149099cb6d12e8ec62601c66086442a427ff18eb6cd5fd6350451646d5db0", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.5", [hex: :qex, repo: "hexpm", optional: false]}, {:secure_random, "~> 0.5", [hex: :secure_random, repo: "hexpm", optional: false]}], "hexpm", "8779fe382555046edfc4efefc10a26867e3da9d5010f1b590a61dec210eedc32"},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
"coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm", "b44a691700f7a1a15b4b7e2ff1fa30bebd669929ac8aa43cffe9e2f8bf051cf1"},
"credo": {:hex, :credo, "1.5.2", "5562f1a1693f77e7319fdabac6d17d26de7e6b0a2b57743bca24a89469232f04", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7003506f069866a4e5d6216a7216823b00ed4bcc4bd9c6e449fa6625c411649b"},
"dialyxir": {:hex, :dialyxir, "1.0.0", "6a1fa629f7881a9f5aaf3a78f094b2a51a0357c843871b8bc98824e7342d00a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "aeb06588145fac14ca08d8061a142d52753dbc2cf7f0d00fc1013f53f8654654"},
"credo": {:hex, :credo, "1.5.5", "e8f422026f553bc3bebb81c8e8bf1932f498ca03339856c7fec63d3faac8424b", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "dd8623ab7091956a855dc9f3062486add9c52d310dfd62748779c4315d8247de"},
"dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"},
"earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
"makeup_elixir": {:hex, :makeup_elixir, "0.15.0", "98312c9f0d3730fde4049985a1105da5155bfe5c11e47bdc7406d88e01e4219b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "75ffa34ab1056b7e24844c90bfc62aaf6f3a37a15faa76b07bc5eba27e4a8b4a"},
"makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"},
"membrane_core": {:hex, :membrane_core, "0.6.0", "7f8bef262c9f68c174f6e95acd9c445f4289a2a0fed56801d573f821f96e47f3", [:mix], [{:bunch, "~> 1.3", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 2.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "46163606a3183c4ea46b14c1c199374822388cbb567f54a8a3e66a098b2432a5"},
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
"numbers": {:hex, :numbers, "5.2.1", "8a6e9eeacfb19f4ac30a52c304f565dc53f8e0813b7193812a5b15b93210780c", [:mix], [{:coerce, "~> 1.0", [hex: :coerce, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "1fd66efe26b67456ad0b80a038f553b89702d073a6942ecd34ce1a3e10af4c92"},
Expand Down
19 changes: 11 additions & 8 deletions test/ex_libnice_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ defmodule ExLibniceTest do
{:ok, pid} =
ExLibnice.start_link(
parent: self(),
stun_servers: ["64.233.161.127:19302"],
stun_servers: [
%{server_addr: {64, 233, 161, 127}, server_port: 19_302},
%{server_addr: "stun1.l.google.com", server_port: 19_302}
],
controlling_mode: true,
port_range: 0..0
)
Expand Down Expand Up @@ -38,7 +41,7 @@ defmodule ExLibniceTest do
stream_id,
1,
%{
server_ip: {127, 0, 0, 1},
server_addr: {127, 0, 0, 1},
server_port: 3478,
username: "username",
password: "password",
Expand All @@ -52,7 +55,7 @@ defmodule ExLibniceTest do
stream_id,
[2, 3],
%{
server_ip: {127, 0, 0, 1},
server_addr: {127, 0, 0, 1},
server_port: 3478,
username: "username",
password: "password",
Expand All @@ -66,7 +69,7 @@ defmodule ExLibniceTest do
stream_id,
:all,
%{
server_ip: {127, 0, 0, 2},
server_addr: {127, 0, 0, 2},
server_port: 3478,
username: "username",
password: "password",
Expand All @@ -80,7 +83,7 @@ defmodule ExLibniceTest do
2,
:all,
%{
server_ip: {127, 0, 0, 1},
server_addr: {127, 0, 0, 1},
server_port: 3478,
username: "username",
password: "password",
Expand All @@ -94,7 +97,7 @@ defmodule ExLibniceTest do
stream_id,
1,
%{
server_ip: {127, 0, 0, 1},
server_addr: {127, 0, 0, 1},
server_port: 3478,
username: "username",
password: "password",
Expand All @@ -108,7 +111,7 @@ defmodule ExLibniceTest do
stream_id,
[3, 5],
%{
server_ip: {127, 0, 0, 1},
server_addr: {127, 0, 0, 1},
server_port: 3478,
username: "username",
password: "password",
Expand All @@ -127,7 +130,7 @@ defmodule ExLibniceTest do
stream_id,
1,
%{
server_ip: {127, 0, 0, 1},
server_addr: {127, 0, 0, 1},
server_port: 3478,
username: "username",
password: "password",
Expand Down
2 changes: 1 addition & 1 deletion test/support/test_peer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ defmodule ExLibnice.Support.TestPeer do
{:ok, ice} =
ExLibnice.start_link(
parent: self(),
stun_servers: ["64.233.161.127:19302"],
stun_servers: [%{server_addr: {64, 233, 161, 127}, server_port: 19_302}],
controlling_mode: controlling_mode,
port_range: 0..0
)
Expand Down

0 comments on commit 856ebd3

Please sign in to comment.