Skip to content

Commit

Permalink
Start mDNS only once per application
Browse files Browse the repository at this point in the history
  • Loading branch information
mickel8 committed Dec 16, 2021
1 parent 9df87cb commit c0942df
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 30 deletions.
46 changes: 16 additions & 30 deletions lib/ex_libnice.ex
Original file line number Diff line number Diff line change
Expand Up @@ -282,12 +282,6 @@ defmodule ExLibnice do
{:ok, state} =
call(impl, :init, [stun_servers, opts[:controlling_mode], min_port, max_port], state)

Logger.debug("Initializing mDNS lookup process")
ret = Mdns.Client.start()
IO.inspect(ret, label: :mdns_client_start)
Logger.debug("Registering for mDNS events")
Mdns.EventManager.register()

{:ok, state}
end

Expand Down Expand Up @@ -437,10 +431,14 @@ defmodule ExLibnice do
withl candidate_check: 6 <- length(candidate_sp),
do: address = Enum.at(candidate_sp, 4),
mdns_check: true <- String.ends_with?(address, ".local") do
Logger.debug("Sending query to resolve mDNS address #{inspect(address)}")
Mdns.Client.query(address)
state = put_in(state, [:mdns_queries, address], {candidate, stream_id, component_id})
{:reply, :ok, state}
if Application.get_env(:ex_libnice, :mdns, true) do
ExLibnice.Mdns.query(self(), address)
state = put_in(state, [:mdns_queries, address], {candidate, stream_id, component_id})
{:reply, :ok, state}
else
Logger.debug("Got mdns address but mdns client is turned off. Ignoring.")
{:reply, :ok, state}
end
else
candidate_check: _ -> {:reply, {:error, :failed_to_parse_sdp_string}, state}
mdns_check: _ -> do_set_remote_candidate(candidate, stream_id, component_id, state)
Expand Down Expand Up @@ -554,27 +552,15 @@ defmodule ExLibnice do
end

@impl true
def handle_info({_namespace, %Mdns.Client.Device{} = dev} = msg, state) do
Logger.debug("mDNS address resolved #{inspect(msg)}")

{query, state} = pop_in(state, [:mdns_queries, dev.domain])
def handle_info({:mdns_response, address, ip}, state) do
{{candidate, stream_id, component_id}, state} = pop_in(state, [:mdns_queries, address])

case query do
nil ->
Logger.debug("""
mDNS response for non existing candidate.
We have probably already resolved address #{inspect(dev.domain)}
""")

{candidate, stream_id, component_id} ->
candidate_parts =
String.split(candidate, " ", parts: 6)
|> List.replace_at(4, :inet.ntoa(dev.ip))

candidate = Enum.join(candidate_parts, " ")
do_set_remote_candidate(candidate, stream_id, component_id, state)
end
candidate_parts =
String.split(candidate, " ", parts: 6)
|> List.replace_at(4, :inet.ntoa(ip))

candidate = Enum.join(candidate_parts, " ")
do_set_remote_candidate(candidate, stream_id, component_id, state)
{:noreply, state}
end

Expand Down Expand Up @@ -704,7 +690,7 @@ defmodule ExLibnice 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, cause, addr}
{:error, cause} -> {:error, cause, addr}
end
end)
end
Expand Down
18 changes: 18 additions & 0 deletions lib/ex_libnice_app.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
defmodule ExLibnice.App do
@moduledoc false
use Application

require Logger

@impl true
def start(_start_type, _start_args) do
children =
if Application.get_env(:ex_libnice, :mdns, true) do
[ExLibnice.Mdns]
else
[]
end

Supervisor.start_link(children, strategy: :one_for_one)
end
end
52 changes: 52 additions & 0 deletions lib/mdns.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
defmodule ExLibnice.Mdns do
@moduledoc """
Module for executing mDNS queries.
"""
use GenServer
require Logger

@spec start_link() :: GenServer.on_start()
def start_link() do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end

@spec query(pid(), String.t()) :: :ok
def query(from, address) do
GenServer.cast(__MODULE__, {:query, from, address})
end

@impl true
def init(_opts) do
Logger.debug("Initializing mDNS lookup process")
:ok = Mdns.Client.start()
Logger.debug("Registering for mDNS events")
Mdns.EventManager.register()
{:ok, %{queries: %{}}}
end

@impl true
def handle_cast({:query, from, address}, state) do
Logger.debug("Sending query to resolve mDNS address #{inspect(address)}")
Mdns.Client.query(address)
state = put_in(state, [:queries, address], from)
{:noreply, state}
end

@impl true
def handle_info({_namespace, %Mdns.Client.Device{} = dev} = msg, state) do
Logger.debug("mDNS address resolved #{inspect(msg)}")

{from, state} = pop_in(state, [:queries, dev.domain])

if from do
send(from, {:mdns_response, dev.domain, dev.ip})
else
Logger.debug("""
mDNS response for non existing query.
We have probably already resolved address #{inspect(dev.domain)}
""")
end

{:noreply, state}
end
end
1 change: 1 addition & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ defmodule ExLibnice.MixProject do

def application do
[
mod: {ExLibnice.App, []},
extra_applications: [:logger]
]
end
Expand Down

0 comments on commit c0942df

Please sign in to comment.