Close search

Hack book of Hoa\Dns

DNS, or Domain Name System, is a system allowing to translate domain names into IP addresses. Names are classified in several types according to services. Hoa\Dns allows to resolve domain names based on their types.

Table of contents

  1. Introduction
  2. Resolving its own domain names
    1. Specifying a resolution server
      1. With Mac OS X
      2. With Linux
    2. Create its own resolution server
  3. Test
  4. In command line
  5. Conclusion


Every machine connected to a network has an IP address (stands for Internet Protocol). There is several versions of this protocol: the IPv4 version, formely standardized in the RFC791, and the IPv6 version, formely standardized in the RFC2460. These addresses are numerical and it is not always easy to remember them. That's why DNS allows to map names to these addresses. We talk about domain names, and traduction, or resolution or even association.

This name system is hierarchical and has a tree structure. Under the root of this tree, we have first level domain, also called TLD for Top Level Domain; for instance: net, org, com etc. Below, we have other domains, like hoa-project, wikipedia, php etc. And still below, we have other domains, like git for We say that is a sub-domain of net, just like is a sub-domain of the hierarchical aspect is present.

But this name system is also distributed. When we try to resolve a domain name, we start by looking for hosts being able to resolve its TLD, then its sub-domain and so on. Each machine has a program called a local resolver of domain names, which is able to find appropriated hosts in order to resolve domain names. We can modify these resolvers to use our own resolution server. Hoa\Dns allows to create such a server. If no server is specified, the local resolver will ask third-services: the distributed aspect is present.

In addition, domain names are classified based on types, like:

The complete list of all types is maintained by the IANA, which is the organism responsible to manage the IP addressing space along with protocols. The whole DNS protocol is specified in the RFC6195.

Thanks to domain name and its type, the resolver will be able to find its associated IP address, or, else, it will find another resolver. Once the IP address is found, requests could be routed correctly.

Finally, the DNS protocol works in UDP or TCP on the 53 port, respectively according to the RFC768 and RFC793.

Resolving its own domain names

Our goal is to resolve domain names of the form *.hoa. We will start by modifying our local resolver by adding a resolution host made with Hoa\Dns.

Specifying a resolution server

There is several resolution programs according to the systems. Our goal is to specify a resolution server for the *.hoa domains. Our server will listen the 57005 port (i.e. 0xDEAD, in order to not have to run our server with root permissions) on the address.

With Mac OS X

With Mac OS X, it is enough to create a /etc/resolver/tld file (be aware to have root permissions, and the /etc/resolver directory does not always exist, do not hesitate to create it). Thus, we will edit the /etc/resolver/hoa file:

port 57005

You probably have to wait few seconds the local server cache to be emptied before reading further.

With Linux

With Linux, we will use DNSMasq, often installed by default. Next, we will modify the /etc/dnsmasq.conf to delegate the *.hoa domains resolution to our own server:


Do not forget to restart DNSMasq:

$ sudo /etc/init.d/dnsmasq restart
 * Restarting DNS forwarder and DHCP server dnsmasq                         [OK]

Create its own resolution server

We will create a server that listens the address in UDP. This server will be given to Hoa\Dns\Resolver, and all will be written in the Resolver.php file:

$dns = new Hoa\Dns\Resolver(
    new Hoa\Socket\Server('udp://')

Hoa\Dns\Resolver fires only one event: query, and sends an array containing domain (for example, type (for example aaaa) and class (for example in). We will associate the IP address to all *.hoa domains, we will not consider sub-domains of hoa in this exercise.

$dns->on('query', function (Hoa\Event\Bucket $bucket) {
    $data = $bucket->getData();

        'Resolving domain ', $data['domain'],
        ' of type ', $data['type'], "\n";

    return '';

Pretty simple no? Notice that we do not consider the domain type (which should be A or AAAA).


To test and play, we will create a file /tmp/index.html containing:

  yeah \o/

To reach this file, we will start an HTTP server, for instance Bhoa, on the address. If this server receives a request from a *.hoa domain it means that our resolution server has worked. The /tmp/index.html file is only present to get a full example. Let's start Bhoa:

$ hoa http:bhoa --root /tmp --listen

Let's also start our resolution server:

$ php Resolver.php

Finally, we can test the whole system, for instance with cURL:

$ curl foo.hoa:8888 --verbose
* About to connect() to foo.hoa port 8888 (#0)
*   Trying connected
* Connected to foo.hoa ( port 8888 (#0)
> GET / HTTP/1.1
> User-Agent: curl/a.b.c (…) libcurl/d.e.f
> OpenSSL/g.h.i zlib/j.k.l
> Host: foo.hoa:8888
> Accept: */*
< HTTP/1.1 200 OK
< Date: …
< Server: Hoa+Bhoa/x.y
< Content-Type: text/html
< Content-Length: 8
yeah \o/
* Connection #0 to host foo.hoa left intact
* Closing connection #0

We see that foo.hoa is correctly resolved into The foo.hoa:8888 request is captured by our HTTP server which will be respond the content of /tmp/index.html.

In command line

Hoa\Dns provides the dns:server command based on the hoa script. This command allows to quickly start a resolution server and to redirect some domains to IP addresses. The matching is based on regular expressions (please, see PCRE). Thus:

$ hoa dns:resolve 'foo.*' to '.*\.bar\..*' to
Server is up, on udp://!


Consequently, all the names starting by foo will be resolved into and those containing .bar. will be resolved into The syntax is pretty simple: regex to ip.

This command is very simple and can be useful to test quickly.


The Hoa\Dns library allows to create a resolution server of domain names. Its simple API allows for instance to quickly create development environments (with *.dev domains for example) or to deploy services (by filtering types) on a local networks or larger.

An error or a suggestion about the documentation? Contributions are welcome!