Compare commits
8 Commits
staging
...
remove-dns
Author | SHA1 | Date |
---|---|---|
Rick Carlino | c480887d16 | |
Rick Carlino | 3453a9c39b | |
Rick Carlino | b0b0a0f6e3 | |
Rick Carlino | 9716651107 | |
Rick Carlino | 561554aefa | |
Rick Carlino | ad13dfc8bf | |
Rick Carlino | fe3732a7b6 | |
Connor Rigby | 5e483c01e2 |
|
@ -10,22 +10,7 @@ config :vintage_net,
|
|||
persistence: VintageNet.Persistence.Null,
|
||||
config: [
|
||||
{"wlan0", %{type: VintageNet.Technology.Null}},
|
||||
{"usb0",
|
||||
%{
|
||||
type: FarmbotOS.Platform.Target.Configurator.CaptivePortal,
|
||||
ipv4: %{
|
||||
method: :static,
|
||||
address: "192.168.25.1",
|
||||
netmask: "255.255.255.0"
|
||||
},
|
||||
dnsmasq: %{
|
||||
domain: "farmbot",
|
||||
server: "192.168.25.1",
|
||||
address: "192.168.25.1",
|
||||
start: "192.168.25.2",
|
||||
end: "192.168.25.10"
|
||||
}
|
||||
}}
|
||||
{"usb0", %{type: VintageNetDirect}}
|
||||
]
|
||||
|
||||
config :mdns_lite,
|
||||
|
|
|
@ -10,22 +10,7 @@ config :vintage_net,
|
|||
persistence: VintageNet.Persistence.Null,
|
||||
config: [
|
||||
{"wlan0", %{type: VintageNet.Technology.Null}},
|
||||
{"usb0",
|
||||
%{
|
||||
type: FarmbotOS.Platform.Target.Configurator.CaptivePortal,
|
||||
ipv4: %{
|
||||
method: :static,
|
||||
address: "192.168.25.1",
|
||||
netmask: "255.255.255.0"
|
||||
},
|
||||
dnsmasq: %{
|
||||
domain: "farmbot",
|
||||
server: "192.168.25.1",
|
||||
address: "192.168.25.1",
|
||||
start: "192.168.25.2",
|
||||
end: "192.168.25.10"
|
||||
}
|
||||
}}
|
||||
{"usb0", %{type: VintageNetDirect}}
|
||||
]
|
||||
|
||||
config :mdns_lite,
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
defmodule FarmbotOS.Configurator.CaptiveDNS do
|
||||
use GenServer
|
||||
alias __MODULE__, as: State
|
||||
|
||||
defstruct [:dns_socket, :dns_port, :ifname]
|
||||
|
||||
def start_link(ifname, port) do
|
||||
GenServer.start_link(__MODULE__, [ifname, port])
|
||||
end
|
||||
|
||||
@impl GenServer
|
||||
def init([ifname, port]) do
|
||||
send(self(), :open_dns)
|
||||
# use charlist here because :inet module works with charlists
|
||||
{:ok, %State{dns_port: port, ifname: to_charlist(ifname)}}
|
||||
end
|
||||
|
||||
@impl GenServer
|
||||
# open a UDP socket on port 53
|
||||
def handle_info(:open_dns, state) do
|
||||
case :gen_udp.open(state.dns_port, [:binary, active: true, reuseaddr: true]) do
|
||||
{:ok, socket} ->
|
||||
{:noreply, %State{state | dns_socket: socket}}
|
||||
|
||||
error ->
|
||||
{:stop, error, state}
|
||||
end
|
||||
end
|
||||
|
||||
# binary dns message from the socket
|
||||
def handle_info(
|
||||
{:udp, socket, ip, port, packet},
|
||||
%{dns_socket: socket} = state
|
||||
) do
|
||||
record = DNS.Record.decode(packet)
|
||||
{answers, state} = handle_dns(record.qdlist, [], state)
|
||||
response = DNS.Record.encode(%{record | anlist: answers})
|
||||
_ = :gen_udp.send(socket, ip, port, response)
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
# recursively check for dns queries, respond to each of them with the local ip address.
|
||||
|
||||
# respond to `a` with our current ip address
|
||||
defp handle_dns(
|
||||
[%{type: :a} = q | rest],
|
||||
answers,
|
||||
state
|
||||
) do
|
||||
ifname = state.ifname
|
||||
{:ok, interfaces} = :inet.getifaddrs()
|
||||
{^ifname, ifinfo} = List.keyfind(interfaces, ifname, 0)
|
||||
|
||||
addr =
|
||||
Enum.find_value(ifinfo, fn
|
||||
{:addr, {_, _, _, _} = ipv4_addr} -> ipv4_addr
|
||||
_ -> false
|
||||
end)
|
||||
|
||||
answer = make_record(q.domain, q.type, 120, addr)
|
||||
handle_dns(rest, [answer | answers], state)
|
||||
end
|
||||
|
||||
# stop recursing when qdlist is fully enumerated
|
||||
defp handle_dns([], answers, state) do
|
||||
{Enum.reverse(answers), state}
|
||||
end
|
||||
|
||||
defp make_record(domain, type, ttl, data) do
|
||||
%DNS.Resource{
|
||||
domain: domain,
|
||||
class: :in,
|
||||
type: type,
|
||||
ttl: ttl,
|
||||
data: data
|
||||
}
|
||||
end
|
||||
end
|
||||
FarmbotOS.Configurator.CaptiveDNS.start_link("lo0", 4040)
|
|
@ -92,6 +92,7 @@ defmodule FarmbotOS.MixProject do
|
|||
{:cors_plug, "~> 2.0"},
|
||||
{:plug_cowboy, "~> 2.1"},
|
||||
{:phoenix_html, "~> 2.13"},
|
||||
{:dns, "~> 2.1"},
|
||||
|
||||
# Nerves stuff.
|
||||
{:nerves, "~> 1.5", runtime: false},
|
||||
|
|
|
@ -6,6 +6,7 @@ defmodule FarmbotOS.Platform.Target.Configurator.CaptivePortal do
|
|||
|
||||
@behaviour VintageNet.Technology
|
||||
require FarmbotCore.Logger
|
||||
alias FarmbotOS.Configurator.CaptiveDNS
|
||||
|
||||
@impl VintageNet.Technology
|
||||
def normalize(%{vintage_net_wifi: _} = config) do
|
||||
|
@ -24,7 +25,7 @@ defmodule FarmbotOS.Platform.Target.Configurator.CaptivePortal do
|
|||
|
||||
ifname
|
||||
|> vintage_wifi(normalized, opts)
|
||||
|> dnsmasq(opts)
|
||||
|> add_captive_dns()
|
||||
end
|
||||
|
||||
def to_raw_config(ifname, config, opts) do
|
||||
|
@ -32,7 +33,7 @@ defmodule FarmbotOS.Platform.Target.Configurator.CaptivePortal do
|
|||
|
||||
ifname
|
||||
|> vintage_ethernet(normalized, opts)
|
||||
|> dnsmasq(opts)
|
||||
|> add_captive_dns()
|
||||
end
|
||||
|
||||
@impl VintageNet.Technology
|
||||
|
@ -45,67 +46,12 @@ defmodule FarmbotOS.Platform.Target.Configurator.CaptivePortal do
|
|||
VintageNetWiFi.ioctl(ifname, ioctl, args)
|
||||
end
|
||||
|
||||
defp dnsmasq(
|
||||
%{ifname: ifname, source_config: %{dnsmasq: config}} = raw_config,
|
||||
opts
|
||||
) do
|
||||
tmpdir = Keyword.fetch!(opts, :tmpdir)
|
||||
killall = Keyword.fetch!(opts, :bin_killall)
|
||||
dnsmasq = System.find_executable("dnsmasq")
|
||||
dnsmasq_conf_path = Path.join(tmpdir, "dnsmasq.conf.#{ifname}")
|
||||
dnsmasq_lease_file = Path.join(tmpdir, "dnsmasq.leases.#{ifname}")
|
||||
dnsmasq_pid_file = Path.join(tmpdir, "dnsmasq.pid.#{ifname}")
|
||||
|
||||
dnsmasq_conf_contents = """
|
||||
interface=#{ifname}
|
||||
except-interface=lo
|
||||
localise-queries
|
||||
bogus-priv
|
||||
bind-interfaces
|
||||
listen-address=#{config[:address]}
|
||||
server=#{config[:address]}
|
||||
address=/#/#{config[:address]}
|
||||
dhcp-option=6,#{config[:address]}
|
||||
dhcp-range=#{config[:start]},#{config[:end]},12h
|
||||
"""
|
||||
|
||||
files = [
|
||||
{dnsmasq_conf_path, dnsmasq_conf_contents}
|
||||
defp add_captive_dns(%{ifname: ifname} = raw_config) do
|
||||
child_specs = [
|
||||
{CaptiveDNS, [ifname, 53]}
|
||||
]
|
||||
|
||||
up_cmds = [
|
||||
{:run, dnsmasq,
|
||||
[
|
||||
"-K",
|
||||
"-l",
|
||||
dnsmasq_lease_file,
|
||||
"-x",
|
||||
dnsmasq_pid_file,
|
||||
"-C",
|
||||
dnsmasq_conf_path
|
||||
]}
|
||||
]
|
||||
|
||||
down_cmds = [
|
||||
{:run, killall, ["-q", "-9", "dnsmasq"]}
|
||||
]
|
||||
|
||||
updated_raw_config = %{
|
||||
raw_config
|
||||
| files: raw_config.files ++ files,
|
||||
up_cmds: raw_config.up_cmds ++ up_cmds,
|
||||
down_cmds: raw_config.down_cmds ++ down_cmds,
|
||||
cleanup_files:
|
||||
raw_config.cleanup_files ++
|
||||
[dnsmasq_conf_path, dnsmasq_lease_file, dnsmasq_pid_file]
|
||||
}
|
||||
|
||||
updated_raw_config
|
||||
end
|
||||
|
||||
defp dnsmasq(%{} = raw_config, _opts) do
|
||||
FarmbotCore.Logger.error(1, "DNSMASQ Disabled")
|
||||
raw_config
|
||||
%{raw_config | child_specs: raw_config.child_specs ++ child_specs}
|
||||
end
|
||||
|
||||
defp vintage_wifi(ifname, config, opts) do
|
||||
|
|
|
@ -36,10 +36,7 @@ defmodule FarmbotOS.Platform.Target.Network do
|
|||
address: "192.168.24.1",
|
||||
netmask: "255.255.255.0"
|
||||
},
|
||||
dnsmasq: %{
|
||||
domain: "farmbot",
|
||||
server: "192.168.24.1",
|
||||
address: "192.168.24.1",
|
||||
dhcpd: %{
|
||||
start: "192.168.24.2",
|
||||
end: "192.168.24.10"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
defmodule FarmbotOS.Configurator.CaptiveDNSTest do
|
||||
use ExUnit.Case, async: false
|
||||
|
||||
@dig System.find_executable("dig")
|
||||
if @dig do
|
||||
test "all dns queries resolve to local ip address" do
|
||||
{:ok, dns_server} = FarmbotOS.Configurator.CaptiveDNS.start_link("lo0", 4040)
|
||||
res = :os.cmd('dig -p 4040')
|
||||
refute String.contains?(to_string(res), "no servers could be reached")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue