DNS library for Elixir
Tung Dao 46f4fe89ac
Merge pull request #28 from Hermanverschooten/close_socket
2 months ago
config extract server behavior 3 years ago
example update sample server and readme, fix #27 2 months ago
lib Close the UDP socket after use 2 months ago
test switch off failing tests 1 year ago
.formatter.exs add behaviour 1 year ago
.gitignore add docs generator 3 years ago
.travis.yml switch to Travis 10 months ago
LICENSE.md add LICENSE 3 years ago
README.md update sample server and readme, fix #27 2 months ago
mix.exs version bump 10 months ago
mix.lock add behaviour 1 year ago



Hex.pm Hex.pm Build Status

DNS library for Elixir. Currently, the package provides:

  • Elixir structs to interface with inet_dns module.
  • DNS.Server behavior
  • DNS client

Note: the inet_dns module is considered internal to Erlang and subject to change. If this happened this library will be updated to accommodate for that, but for now inet_dns is simple and worked for me.


The package is available in Hex and can be installed as:

  1. Make sure you have the Erlang/OTP source files installed, otherwise the compilation will fail with an {:error, :enoent} message. On Ubuntu, this can be done using apt-get install erlang-src.

  2. Add dns to your list of dependencies in mix.exs:

    def deps do
      [{:dns, "~> 2.1.2"}]


DNS client

iex> DNS.resolve("google.com")
{:ok, [{216, 58, 221, 110}]}

iex> DNS.resolve("notfound.domain")
{:error, :not_found}

iex> DNS.query("google.com")
%DNS.Record{anlist: [%DNS.Resource{bm: [], class: :in, cnt: 0,
   data: {216, 58, 221, 110}, domain: 'google.com', func: false, tm: :undefined,
   ttl: 129, type: :a}], arlist: [],
 header: %DNS.Header{aa: false, id: 0, opcode: :query, pr: false, qr: true,
  ra: true, rcode: 0, rd: false, tc: false}, nslist: [],
 qdlist: [%DNS.Query{class: :in, domain: 'google.com', type: :a}]}

iex> DNS.resolve("google.com", :a, {"", 53})

DNS server

defmodule ServerExample do
  @moduledoc """
  Example implementing DNS.Server behaviour
  @behaviour DNS.Server
  use DNS.Server

  def handle(record, _cl) do
    Logger.info(fn -> "#{inspect(record)}" end)
    query = hd(record.qdlist)

    result =
      case query.type do
        :a -> {127, 0, 0, 1}
        :cname -> 'your.domain.com'
        :txt -> ['your txt value']
        _ -> nil

    resource = %DNS.Resource{
      domain: query.domain,
      class: query.class,
      type: query.type,
      ttl: 0,
      data: result

    %{record | anlist: [resource], header: %{record.header | qr: true}}

To run the example server in iex:

iex(1)> c "example/test_server.ex"
iex(2)> {:ok, server_pid} = ServerExample.start_link 8000
Server listening at 8000
{:ok, #PID<0.180.0>}
iex(3)> Process.exit(server_pid, :normal)

For more information, see API Reference