Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion lib/mdns_lite/responder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ defmodule MdnsLite.Responder do
skip_udp: boolean()
}

def announce_services(iface_name, iface_address) do
Process.send(via_name({iface_name, iface_address}), :announce_services, [])
end
##############################################################################
# Public interface
##############################################################################
Expand Down Expand Up @@ -143,7 +146,7 @@ defmodule MdnsLite.Responder do
:ok <- :socket.bind(udp, %{family: family, port: @mdns_port}),
:ok <- add_membership(udp, interface, family) do
new_state = %{state | udp: udp} |> process_receives()
{:noreply, new_state}
{:noreply, new_state, {:continue, :announce_services}}
else
{:error, reason} ->
Logger.error("mdns_lite #{state.ifname}/#{inspect(state.ip)} failed: #{inspect(reason)}")
Expand All @@ -154,6 +157,13 @@ defmodule MdnsLite.Responder do
end
end

def handle_continue(:announce_services, state) do
# TODO: The wait here is not necessary and needs to be removed
Process.send_after(self(), {:announce_services, 0}, 15000)

{:noreply, state}
end

@impl GenServer
def handle_call(:get_cache, _from, state) do
new_state = gc_cache(state)
Expand Down Expand Up @@ -192,6 +202,29 @@ defmodule MdnsLite.Responder do
{:noreply, process_receives(state)}
end

def handle_info({:announce_services, 3}, state) do
Logger.info("Services have been announced")
{:noreply, state}
end

def handle_info({:announce_services, count}, state) do

# For all services defined run a query to force sending unsolicidted announcement
TableServer.options()
|> Map.get(:services)
|> Enum.map(fn service ->
run_query(
dns_query(class: :in, domain: ~c"#{service.type}.local", type: :ptr),
dns_rec(header: dns_header()),
%{port: @mdns_port, addr: state.ip, family: :inet},
state
)
end)

Process.send_after(self(), {:announce_services, count + 1}, 1000)
{:noreply, state}
end

def handle_info(msg, state) do
Logger.error("mdns_lite responder ignoring #{inspect(msg)}, #{inspect(state)}")
{:noreply, state}
Expand Down
1 change: 1 addition & 0 deletions lib/mdns_lite/responder_supervisor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ defmodule MdnsLite.ResponderSupervisor do
@impl DynamicSupervisor
def init(_init_arg) do
DynamicSupervisor.init(strategy: :one_for_one)
# TODO: See Section 8.1 of standard
end
end
1 change: 1 addition & 0 deletions lib/mdns_lite/table/builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule MdnsLite.Table.Builder do
@spec from_options(Options.t()) :: MdnsLite.Table.t()
def from_options(%Options{} = config) do
# TODO: This could be seriously simplified...
# CHRIS TODO: Announce service after they are all added
[]
|> add_a_records(config)
|> add_ptr_records(config)
Expand Down