View Source Exagon Zeroconf

Exagon Zerconf module

Exagon Zeronconf provides utilites for interfacing Exagon with Zeronconf devices:

  • MDNS server
  • DNS-SD service discrovery

installation

Installation

This package can be installed by adding exagon_zeroconf to your list of dependencies in mix.exs:

def deps do
  [
    {:exagon_zeroconf, "~> 0.1.0"}
  ]
end

integration

Integration

Exagon.Zeronconf can be used transparently by adding Exagon.Zeroconf.Application to your application modules lists in miex.exs.

def application do
    [
      extra_applications: [:logger],
      mod: {Exagon.Zeroconf.Application, []}
    ]
  end

Exagon.Zeronconf can also be started manually by adding and starting Exagon.Zeroconf.Supervisor in your supervision tree.

multicast-dns-server

Multicast DNS server

Exagon.Zeroconf.Mdns.Server manage Multicast DNS server request/answer. It is configured to listen on port 5353 on both IPv4 (224.0.0.251) and/or IPv6 (ff02::fb).

DNS records found my Exagon.Zeroconf.Mdns.Server can be requested through Exagon.Zeroconf.Mdns.Server.dump/0 :

Exagon.Zeroconf.Mdns.Server.dump
[
  %DNS.Resource{
    domain: 'My iPhone._rdlink._tcp.local',
    type: 47,
    class: :in,
    cnt: 0,
    ttl: 4500,
    data: <<192, 12, 0, 5, 0, 0, 128, 0, 64>>,
    tm: :undefined,
    bm: [],
    func: true
  },
  %DNS.Resource{
    domain: 'My iPhone.local',
    type: 47,
    class: :in,
    cnt: 0,
    ttl: 120,
    data: <<192, 236, 0, 4, 64, 0, 0, 8>>,
    tm: :undefined,
    bm: [],
    func: true
  },
  %DNS.Resource{
    domain: 'My iPhone.local',
    type: :a,
    class: :in,
    cnt: 0,
    ttl: 120,
    data: {192, 168, 1, 5},
    tm: :undefined,
    bm: [],
    func: true
  },
  %DNS.Resource{
    domain: 'My iPhone.local',
    type: :aaaa,
    class: :in,
    cnt: 0,
    ttl: 120,
    data: {8193, 2145, 13574, 1056, 58674, 15752, 37663, 62405},
    tm: :undefined,
    bm: [],
    func: true
  },

Exagon.Zeroconf.Mdns.Server.subscribe/0 provides a way to subscribe for notifications about added, changed or removed records. Notifications use Phoenix PubSub.

configuration

Configuration

config :exagon_zeroconf, :mdns,
  port: 5353,
  use_ipv4: true,
  use_ipv6: false,
  hostname: "exagon",
  domain_name: ".local"

dns-sd

DNS-SD

service-discovery

Service Discovery

Exagon.Zeroconf.Mdns.Dnssd provides DNS service discovery over multicast DNS. It uses Exagon.Zeroconf.Mdns.Dnssd.Server to listen for DNS-SD relevand records and build a list of discovred services.

At anytime, a list of found services is available by calling Exagon.Zeroconf.Mdns.Dnssd.query/1 which accepts an optional domain parameter:

[
  %Exagon.Zeroconf.Mdns.Dnssd.Service{
    domain: "_smb._tcp.local",
    instance_name: "Windows._smb._tcp.local",
    ip: nil,
    priority: 0,
    weight: 0,
    port: 445,
    target: "Windows.local",
    additional_info: nil,
    records: [:srv, :txt, :ptr]
  },
  %Exagon.Zeroconf.Mdns.Dnssd.Service{
    domain: "_spotify-connect._tcp.local",
    instance_name: "75c62f4dfb4ab9e7._spotify-connect._tcp.local",
    ip: {192, 168, 1, 12},
    priority: 0,
    weight: 0,
    port: 39753,
    target: "75c62f4dfb4ab9e7.local",
    additional_info: %{"cpath" => "/zc/0", "stack" => "SP", "version" => "1.0"},
    records: [:txt, :srv, :ptr]
  }
]

service-integration

Service integration

At anytime DNS-SD service can be added to Exagon.Zeroconf.Mdns.Dnssd. DNS records (PTR, SRV, TXT, A, AAAA) will be generated and broadcasted to the network.

For example, running the following code will integrate a new DNS-SD service:

%Exagon.Zeroconf.Mdns.Dnssd.Service{
      domain: "_exagon._tcp.local",
      instance_name: "test._exagon._tcp.local",
      ip4: {192, 168, 1, 99},
      ip6: {65282, 1234, 5678, 9012, 458, 12, 7894, 124},
      priority: 0,
      weight: 0,
      port: 39753,
      target: "test.exagon.local",
      additional_info: %{
        "some" => "info",
        "other" => "good",
        "version" => "1.0"
      },
    }
|> Exagon.Zeroconf.Mdns.Dnssd.add_service

will be discoreved by commands like :

$ avahi-browse -d local _exagon._tcp --resolve
+  ens18 IPv4 test                                          _exagon._tcp         local
=  ens18 IPv4 test                                          _exagon._tcp         local
   hostname = [test.exagon.local]
   address = [192.168.1.99]
   port = [39753]
   txt = ["some=info" "other=good" "version=1.0"]

or :

$ dns-sd -Z _exagon._tcp local                                                                    ✔  took 26s  at 17:38:21
Browsing for _exagon._tcp.local
DATE: ---Sun 29 Jan 2023---
17:38:30.889  ...STARTING...

; To direct clients to browse a different domain, substitute that domain in place of '@'
lb._dns-sd._udp                                 PTR     @

; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names.
; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local
; names with the correct fully-qualified (unicast) domain name of the target host offering the service.

_exagon._tcp                                    PTR     test._exagon._tcp
test._exagon._tcp                               SRV     0 0 39753 test.exagon.local. ; Replace with unicast FQDN of target host
test._exagon._tcp                               TXT     "some=info" "other=good" "version=1.0"

Documentation is generated with ExDoc and published at https://hexdocs.pm/exagon_zeroconf.