.. _UDPSockets:

.. raw:: html

   <script>ODSA.SETTINGS.DISP_MOD_COMP = true;ODSA.SETTINGS.MODULE_NAME = "UDPSockets";ODSA.SETTINGS.MODULE_LONG_NAME = "UDP Socket Programming: DNS";ODSA.SETTINGS.MODULE_CHAPTER = "Networked Concurrency"; ODSA.SETTINGS.BUILD_DATE = "2021-06-01 12:51:47"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script>


.. |--| unicode:: U+2013   .. en dash
.. |---| unicode:: U+2014  .. em dash, trimming surrounding whitespace
   :trim:


.. This file is part of the OpenCSF eTextbook project. It was
.. auto-generated by scripts from the OpenDSA eTextbook project.
.. See https://OpenCSF.org for more details. OpenCSF is distributed
.. under a Creative Commons Attribution-NonCommercial 4.0 International
.. License (see http://creativecommons.org/licenses/by-nc/4.0/),
.. Copyright (c) 2019-2021 by Michael S. Kirkpatrick. OpenDSA is
.. distributed under an MIT open source license, Copyright (c) 2012-2021
.. by the OpenDSA Project Contributors.

.. avmetadata::
   :author: Michael S. Kirkpatrick
   :requires:
   :satisfies: 
   :topic: 

UDP Socket Programming: DNS
===========================

.. _DNSHier:

.. figure:: Images/CSF-Images.4.11.png
   :align: right
   :width: 95%
   :figwidth: 40%
   :alt: The DNS name space is organized as a hierarchy of zones of authority

   The DNS name space is organized as a hierarchy of zones of authority

The :term:`Domain Name System` (DNS) is a distributed database that resolves human-readable URLs
(such as ``stuff.com`` or ``k12.county.edu``) into IP addresses. The basic structure and operation
of DNS is defined in RFCs 1034 and 1035. DNS defines a hierarchical name space, illustrated in
:num:`Figure #DNSHier`, that are controlled by multiple :term:`name servers <name server>`. At the
highest level is the :term:`root name server`, which is denoted with a dot (``"."``). The
:term:`Internet Corporation for Assigned Names and Numbers` (ICANN) is a nonprofit organization that
governs and maintains the root structures of the DNS hierarchy. The level just below the root is the
set of :term:`top-level domains <top-level domain>` (TLDs), which provide structure based on the
type of service that the registered organization provides. Each TLD is governed and maintained by a
separate company or organization, such as Verisign. These organizations coordinate their work with
ICANN to maintain the core of the DNS hierarchy.

Levels in the DNS hierarchy are indicated by dots within the domain name. For instance, an education
institution (such as a university or school district) would register their domain names under the
``.edu`` TLD, establishing ownership of a domain name such as ``university.edu``. Commercial
enterprises and other businesses use the ``.com`` TLD, reserving domain names like ``business.com``.
Non-profit organizations register domain names under the ``.org`` TLD, establishing names like
``charity.org``.

.. topic:: Note

   .. figure:: Images/CSF-Images-Note.png
      :align: left
      :width: 100%
      :alt: Decorative note icon

   The names ``university.edu``, ``business.com``, and ``charity.org`` are intended to illustrate the
   types of entities that might use these TLDs. These domains are actually registered to real
   organizations (CapStone University, a private registrant, and Global Impact, respectively). None of
   the addresses or descriptions in this section are intended to refer to these specific entities.

Organizations themselves can extend the DNS hierarchy based on their own needs and services. The
organizations manage this by setting up and running their own authoritative name servers. For
instance, ``charity.org`` might use the separate domain names ``mail.charity.org`` and
``www.charity.org`` to distinguish their email server from the server for their web page. These
names are considered subdomains of the ``charity.org`` domain name.

.. topic:: Bug Warning

   .. figure:: Images/CSF-Images-BugWarning.png
      :align: left
      :width: 90%
      :alt: Decorative bug warning

   Once an organization has registered a domain name with the appropriate TLD, that organization has
   established control of all subdomains within their zone of authority. That is, the organization
   that has set up the authoritative name server for ``charity.org`` has administrative control over
   every domain name that ends with those fields. Note, though, that this control does not extend to
   similar-looking domain names. The key distinction is the presence of the ``"."`` immediately
   preceding ``charity.org`` in a domain name. That is, the owners of ``charity.org`` would have the
   authority for the domain names ``mail.charity.org`` and ``www.charity.org``; they would not,
   however, have control over ``mailcharity.org`` or ``wwwcharity.org``. Registering similar-looking
   domain names is a common technique for criminal or other malicious groups that are attempting to
   take advantage of users who make a mistake typing the URL or those who might overlook the missing
   ``"."`` as part of a spam email message in a phishing attack.

DNS is designed to be a resilient system for resolving addresses. As such, there is not actually a
single root DNS server. As of this writing, there are currently 13 root servers operating
world-wide. These 13 root servers communicate with each other to maintain a consistent database of
IP addresses for the TLD servers. Again, as of this writing, there are currently over 1500 TLD
extensions. These extensions include the original seven TLDs (``.com``, ``.edu``, ``.gov``,
``.int``, ``.mil``, ``.net``, and ``.org``). Other TLD extensions indicate country codes (such as
``.uk`` for the United Kingdom or ``.ca`` for Canada), though many companies repurposed country
codes to make their domain names more readable. Some examples of this practice include
``del.icio.us`` and ``bit.ly``, which used the country codes for the United State and Libya to
create readable domain names; in the former case, a company registered the domain name ``icio.us``
with the US domain registrar, then created the ``del.icio.us`` entry within its own authoritative
name server. In more recent years, ICANN has expanded the TLD extensions to include topical names,
such as ``.car``, ``.hospital``, or ``.restaurant``.

Resolving DNS Queries
---------------------

To translate a domain name into an IP address, a user program (such as a web browser) contacts a
local process known as a *resolver*. The resolver maintains a *master file* that
contains a local database of pre-defined addresses along with a cache of recently translated
addresses. If the master file contains the address for the requested domain name, the resolver can
return the answer immediately. For addresses that are not in the master file, the resolver would
then consult the larger DNS structure. The pre-defined addresses in the master file include the
addresses of the 13 root servers. For instance, the root name server ``a.root-servers.net`` has a
persistent IP address of 198.41.0.4. These addresses serve as the entry point to the Internet's DNS
database.

DNS defines two strategies that resolvers can adopt. In the *iterative* strategy, a DNS
resolver will send repeated queries to different servers until it can resolve the request. For
instance, a home user's laptop may send a DNS request to their ISP or a public DNS service like
OpenDNS. This DNS resolver had only the root server addresses, it would contact a root server to get
the address of the TLD server; this same DNS resolver would then send a request to the TLD
requesting the address of the authoritative name server, and so on. In the *recursive*
strategy, the DNS resolver would simply forward the request to a different resolver that would take
control. This approach is illustrated by the same scenario, because the laptop itself has a DNS
resolver; instead of iteratively contacting the name servers to resolve the request, the laptop sent
a single request to the ISP DNS resolver or OpenDNS. The DNS specification requires all resolvers
implement an iterative solution, while the recursive strategy is optional.

.. _DNSIter:

.. figure:: Images/CSF-Images.4.12.png
   :align: right
   :width: 95%
   :figwidth: 55%
   :alt: Iterative sequence of DNS requests

   Iterative sequence of DNS requests

:num:`Figure #DNSIter` illustrates the iterative sequence of messages sent when a web browser
tries to resolve ``www.charity.org``. [#f27]_ The resolver finds the root server address and sends a
query to 198.41.0.4 to look up the ``.org`` TLD address. The root name server responds with
199.19.56.1 as the address for the ``.org`` TLD name server. The resolver then contacts that server
to get the address of the authoritative name server for ``.charity.org``, which is at address
12.34.56.78. Finally, the resolver contacts the authoritative name server that indicates
``www.charity.org`` can be found at 12.34.56.80.

If every DNS query required the steps in :num:`Figure #DNSIter`, the system would suffer from
terrible performance. Every time someone accessed a web page, sent an email, or streamed a piece of
music, the client would have to contact one of the 13 root servers; these servers would quickly
crash from the strain of handling these requests. Instead, all levels of the DNS system employ an
extensive amount of caching. As such, except under rare circumstances, the master file on the local
machine already has the IP address for the ``.org`` TLD when the original request is received.
Similarly, if the request for ``www.charity.org`` is followed by requests for ``www-1.charity.org``,
``mail.charity.org``, or any other subdomain, the resolver would not contact either the root or
``.org`` TLD name servers, as the resolver's cache would already have the address of the needed
authoritative name server. In addition to caching, the TLD and authoritative name servers also
employ :term:`replication` across multiple IP addresses. That is, 199.19.56.1 is one of several IP
addresses that correspond to the ``.org`` TLD. The resolver can contact any of these addresses and
is likely to get the same results.

DNS Resource Record Structure
-----------------------------

The translation information for DNS queries are stored and sent in structures known as
*resource records*. `Table 4.6 <#tbl4-6>`_ shows the generic structure of
every resource record. The ``NAME`` and ``RDATA`` fields (indicated with the wavy lines in the
table) are variable length; all other fields are exactly 16 bits wide. The ``NAME`` field (also
called the owner) is the human-readable domain name of the record. The ``TYPE`` provides information
about the resource under consideration, as described below. The ``CLASS`` designates the protocol
stack in use, which is ``IN`` to indicate Internet. The ``TTL`` field indicates how many seconds the
record should be considered valid in the local host's cache; once the record expires, the resolver
should repeat the query to check if the record has been updated. Finally, the ``RDATA`` field
includes the actual data of the record, which is tied to the type, and the ``RDLENGTH`` indicates
the length of ``RDATA``.

.. _tbl4-6:

.. raw:: html

   <center>
   <div class="col-md-6">
   <table class="table table-bordered">
     <thead class="jmu-dark-purple-bg text-light">
       <tr>
         <th class="p-0 center">0</th> <th class="p-0 center">1</th>
         <th class="p-0 center">2</th> <th class="p-0 center">3</th>
         <th class="p-0 center">4</th> <th class="p-0 center">5</th>
         <th class="p-0 center">6</th> <th class="p-0 center">7</th>
         <th class="p-0 center">8</th> <th class="p-0 center">9</th>
         <th class="p-0 center">10</th> <th class="p-0 center">11</th>
         <th class="p-0 center">12</th> <th class="p-0 center">13</th>
         <th class="p-0 center">14</th> <th class="p-0 center">15</th>
       </tr>
     </thead>
     <tbody>
       <tr> <td class="p-0 center" colspan="16"><div class="xborder-highlight"><code>NAME</code></div></td> </tr>
       <tr> <td class="py-0 center" colspan="16"><code>TYPE</code></td> </tr>
       <tr> <td class="py-0 center" colspan="16"><code>CLASS</code></td> </tr>
       <tr> <td class="py-0 center" colspan="16"><code>TTL</code></td> </tr>
       <tr> <td class="py-0 center" colspan="16"><code>RDLENGTH</code></td> </tr>
       <tr> <td class="p-0 center" colspan="16"><div class="xborder-highlight"><code>RDATA</code></div></td> </tr>
     </tbody>
   </table>
   </div>
   <p>
   Table 4.6: Generic structure of a DNS resource record
   </p>
   <br />
   </center>
   

There are several common types of resources records. The ``A`` type denotes a host address, so the
``RDATA`` field would contain the IP address for the domain name. The ``CNAME`` type denotes a
:term:`canonical name` record that maps an alias to the definitive domain name. For instance, a
company might create the subdomains ``ftp.example.com`` and ``www.example.com``, though both of
these addresses are handled by the server identified by the name ``example.com``. Resource records
for example.com would have an ``A`` type with the server's IP address, while resource records for both
``ftp.example.com`` and ``www.example.com`` would have ``CNAME`` type, with ``example.com`` in the
``RDATA`` field. A third common resource record type is ``NS``, which indicates the authoritative name
server for the domain. For instance, the ``RDATA`` field for the ``NS`` record for ``example.com``
would contain the domain name of the authoritative server for the ``example.com`` domain. Finally,
an ``MX`` record type is used to store information about mail exchange servers that are responsible
for delivering email.

To illustrate the example, consider again the fictional scenario in :num:`Figure #DNSIter`. When
the resolver contacted the ``.org`` TLD name server at 199.19.56.1, this server might first reply
with an NS resource record for the ``charity.org`` domain. This authoritative name server might have
a domain name like ``ns.charity.org``, which would be the contents of the ``RDATA`` field for the NS
resource record. To resolve this address, a second response would contain a resource record with the
A type containing the address of the name server 12.34.56.78. Complicating matters further, this
authoritative name server might initially respond with a ``CNAME`` resource record to indicate that
``www.charity.org`` is an alias for ``a0.web.charity.org``. A second response from the
``charity.org`` authoritative name server would then return an A resource record to indicate that
``a0.web.charity.org`` can be accessed at 12.34.56.80.

DNS Protocol Messages
---------------------

Like HTTP/1.0, the DNS protocol is a simple request-response protocol with no persistent state
between messages, but DNS uses UDP instead of TCP. That is, a DNS client can construct the datagram
format specified by the RFC and send it to an arbitrary server as a UDP message with no prior
connection. The server would then respond to the IP address in the UDP datagram header with the
response. The DNS message itself contains five fields. The ``header`` field indicates if the message
contains a query, a response, or another type of message. The question field contains the domain
name that is being queried (the ``QNAME``), along with the class (``QCLASS``) and type (``QTYPE``)
of resource record requested. For a DNS response, the ``answer`` field would contain the resource
record. The ``authority`` and ``additional`` fields provide additional information.

To illustrate the structure of a DNS query and response, consider a request to resolve the domain
name ``example.com``. [#f28]_ `Table 4.7 <#tbl4-7>`_ shows the interpretation of the bytes of the
request. (Note that the exact structure of the UDP datagram consists of just the bytes shown,
concatenated in order: ``123401000001...``) The header starts with a 16-bit randomly chosen
identifier denoted as XID (``1234`` in our example), followed by a 16-bit value that serves as a bit
mask. The structure of the bit mask is shown in `Table 4.8 <#tbl4-8>`_. The rest of the header after the
bit-mask indicates how many entries are in each of the other fields, each as a 16-bit value.

.. _tbl4-7:

.. raw:: html

   <center>
   <table class="table table-bordered">
     <tbody>
       <tr>
         <td class="py-0" rowspan="3">Header</td>
         <td class="py-0"><code>1234</code></td>
         <td class="py-0"><code>XID=0x1234 [random identifier]</code></td>
       </tr>
       <tr>
         <td class="py-0"><code>0100</code></td>
         <td class="py-0"><code>OPCODE=SQUERY</code></td>
       </tr>
       <tr>
         <td class="py-0"><code>0001 0000 0000 0000</code></td>
         <td class="py-0"><code>1 question field</code></td>
       </tr>
       <tr>
         <td class="py-0" rowspan="2">Question</td>
         <td class="py-0"><code>0765 7861 6d70 6c65 0363 6f6d 00</code></td>
         <td class="py-0"><code>QNAME=EXAMPLE.COM.,</code></td>
       </tr>
       <tr>
         <td class="py-0"><code>0001 0001</code></td>
         <td class="py-0"><code>QCLASS=IN, QTYPE=A </code></td>
       </tr>
       <tr>
         <td class="py-0">Answer</td>
         <td class="py-0">&nbsp;</td>
         <td class="py-0"><code>&lt;empty&gt;</code></td>
       </tr>
       <tr>
         <td class="py-0">Authority</td>
         <td class="py-0">&nbsp;</td>
         <td class="py-0"><code>&lt;empty&gt;</code></td>
       </tr>
       <tr>
         <td class="py-0">Additional</td>
         <td class="py-0">&nbsp;</td>
         <td class="py-0"><code>&lt;empty&gt;</code></td>
       </tr>
     </tbody>
   </table>
   <p>
   Table 4.7: Sequence of bytes and their interpretation to query DNS for example.com
   </p>
   <br />
   </center>

`Table 4.8 <#tbl4-8>`_ illustrates the structure of the 16-bit flag field that follows the XID field of
a DNS header. In the message shown in `Table 4.7 <#tbl4-7>`_, the only bit set is the ``Recursion Desired``
(``RD``) bit. The ``Opcode`` field indicates that this is a standard query (``SQUERY = 0000``). In
the response shown in `Table 4.9 <#tbl4-9>`_, the flag value is ``0x8180``, which means that the Query
Response (``QR``) bit has been set to indicate the message is a response, as well as the ``Recursion
Available`` (``RA``) bit. The ``RCODE`` field is used to indicate if an error occurs, and all 0 bits
there indicates there was no error processing the query. Information on the other fields is
available in RFC 1035.

.. _tbl4-8:

.. raw:: html

   <center>
   <table class="table table-bordered">
     <thead class="jmu-dark-purple-bg text-light">
       <tr>
         <td class="py-0 center">Bit Index</td>
         <th class="py-0 center">0</th> <th class="py-0 center">1</th>
         <th class="py-0 center">2</th> <th class="py-0 center">3</th>
         <th class="py-0 center">4</th> <th class="py-0 center">5</th>
         <th class="py-0 center">6</th> <th class="py-0 center">7</th>
         <th class="py-0 center">8</th> <th class="py-0 center">9</th>
         <th class="py-0 center">10</th> <th class="py-0 center">11</th>
         <th class="py-0 center">12</th> <th class="py-0 center">13</th>
         <th class="py-0 center">14</th> <th class="py-0 center">15</th>
       </tr>
     </thead>
     <tbody>
       <tr>
         <td class="py-0 center">Meaning</td>
         <td class="py-0 center"><code>QR</code></td>
         <td class="py-0 center" colspan="4"><code>Opcode</code></td>
         <td class="py-0 center"><code>AA</code></td>
         <td class="py-0 center"><code>TC</code></td>
         <td class="py-0 center"><code>RD</code></td>
         <td class="py-0 center"><code>RA</code></td>
         <td class="py-0 center" colspan="3"><code>Z</code></td>
         <td class="py-0 center" colspan="4"><code>RCODE</code></td>
       </tr>
       <tr>
         <td class="py-0 center">Value</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">1</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
         <td class="py-0 center">0</td>
       </tr>
       <tr>
         <td class="py-0 center">Hex Value</td>
         <td class="py-0 center" colspan="4">0</td>
         <td class="py-0 center" colspan="4">1</td>
         <td class="py-0 center" colspan="4">0</td>
         <td class="py-0 center" colspan="4">0</td>
       </tr>
     </tbody>
   </table>
   <p>
   Table 4.8: Structure of the flags field in a DNS query header
   </p>
   <br />
   </center>

The question field of the request starts with the fields of the domain name, with each field
preceded by the number of bytes in the field. That is, the domain name in the question does not
contain the standard dotted format for the name. In this example, the domain name (``QNAME``
[#f29]_) starts with 7 characters (``65 78 61 6d 70 6c 65 = "EXAMPLE"``) followed by a field with 3
characters (``63 6f 6d = "COM"``). The QNAME continues until the first 0-byte (``00``) is
encountered, as this indicates a 0-length field. The remainder of the question indicate the class
(``0001 = IN``) and the type of resource record sought (``0001 = A``).

`Table 4.9 <#tbl4-9>`_ shows the response for the query from `Table 4.7 <#tbl4-7>`_. In the response, the
``header`` is almost identical to that of the request. The randomly chosen identifier ``XID`` should
match the original request; if the resolver has sent multiple requests, the ``XID`` field allows the
resolver to determine which request is being answered. The bit mask has been modified to denote that
this message is a response and the recursive resolution strategy is available. The ``header`` also
indicates that a single answer has been provided. The ``question`` field is identical to the
original request.

.. raw:: html

   <center>
   <table class="table table-bordered py-0">
     <tbody>
       <tr>
         <td class="py-0" rowspan="3">Header</td>
         <td class="py-0"><code>1234</code></td>
         <td class="py-0"><code>XID=0x1234 [random identifier]</code></td>
       </tr>
       <tr>
         <td class="py-0"><code>8180</code></td>
         <td class="py-0"><code>OPCODE=SQUERY, RESPONSE, RA</code></td>
       </tr>
       <tr>
         <td class="py-0"><code>0001 0001 0000 0000</code></td>
         <td class="py-0"><code>1 question and 1 answer</code></td>
       </tr>
       <tr>
         <td class="py-0" rowspan="2">Question</td>
         <td class="py-0"><code>0765 7861 6d70 6c65 0363 6f6d 00</code></td>
         <td class="py-0"><code>QNAME=EXAMPLE.COM.,</code></td>
       </tr>
       <tr>
         <td class="py-0"><code>0001 0001</code></td>
         <td class="py-0"><code>QCLASS=IN, QTYPE=A </code></td>
       </tr>
       <tr>
         <td class="py-0" rowspan="6">Answer</td>
         <td class="py-0">&nbsp;</td>
         <td class="py-0"><code>&lt;empty&gt;</code></td>
       </tr>
       <tr>
         <td class="py-0"><code>c00c</code></td>
         <td class="py-0"><code>QNAME=EXAMPLE.COM. [compressed]</code></td>
       </tr>
       <tr>
         <td class="py-0"><code>0001</code></td>
         <td class="py-0"><code>QTYPE=A</code></td>
       </tr>
       <tr>
         <td class="py-0"><code>0001</code></td>
         <td class="py-0"><code>QCLASS=IN</code></td>
       </tr>
       <tr>
         <td class="py-0"><code>0000 e949</code></td>
         <td class="py-0"><code>TTL = 0xe949 = 59721</code></td>
       </tr>
       <tr>
         <td class="py-0"><code>04</code></td>
         <td class="py-0"><code>RDLENGTH = 4</code></td>
       </tr>
       <tr>
         <td class="py-0"><code>5db8 d822</code></td>
         <td class="py-0"><code>RDATA = 0x5db8d822 [93.184.216.34]</code></td>
       </tr>
       <tr>
         <td class="py-0">Authority</td>
         <td class="py-0">&nbsp;</td>
         <td class="py-0"><code>&lt;empty&gt;</code></td>
       </tr>
       <tr>
         <td class="py-0">Additional</td>
         <td class="py-0">&nbsp;</td>
         <td class="py-0"><code>&lt;empty&gt;</code></td>
       </tr>
     </tbody>
   </table>
   <p>
   Table 4.9: Sequence of bytes and their interpretation for the example.com DNS response
   </p>
   <br />
   </center>

The answer field contains the resource record, which adheres to the general structure defined in
`Table 4.6 <#tbl4-6>`_. The record is an ``A``-type Internet (``IN`` class) with a time-to-live of
59,721 seconds. The ``RDLENGTH`` indicates a length of four bytes for the ``RDATA``, which contains
an IPv4 address. Note that the address is simply a 32-bit number ``0x4db8d822``; by interpreting
each byte as a separate number, this denotes the dotted decimal address 93.184.216.34.

The ``QNAME`` field of the resource record is employing a compression technique to keep the message
as small as possible. That is, since the question field already contains the domain name, there is
no need to repeat the string in the answer. DNS indicates the compression is being used by setting
the first two bits of the answer field to ``11`` (hence the first byte is ``0xc``). Ignoring those
two bits, the next 14 bits (``0x000c`` after clearing out the two "``11``" bits) indicate the
location of the name as a byte offset within the message. That is, the answer is pointing to the
byte offset 12 (``0xc``) within the datagram, which is where the ``07657861...`` starts.

Constructing DNS Queries with Sockets
-------------------------------------

To illustrate how to work with DNS in code, we start by declaring the following types for a DNS
header and question. The ``dns_header_t`` and ``dns_question_t`` type definitions are those used in
the macOS DNS implementation and are present in the ``dns_util.h`` header file. However, these are
not part of the POSIX standard, so they do not exist on other systems. [#f30]_ We use them here for
convenience to construct the query.

.. codeinclude:: Sockets/DNSStruct.c
   :linenos: true

`Code Listing 4.17 <#cl4-17>`_ illustrates how to start creating a DNS query using the OpenDNS service. This same request could be sent to any DNS server, such as the DNS server operated by the reader's ISP. [#f31]_ As with HTTP before, the code starts by creating a socket, but this socket uses the ``SOCK_DGRAM`` type to create a UDP socket. OpenDNS's DNS server IPv4 address is available at 208.67.222.222, which is the hexadecimal value ``0xd043dede``. DNS servers listen on port 53, so that value is also set. For the DNS header, we can randomly assign any value to the ``XID`` field, which has no inherent meaning to the server itself. The flag field is set to declare the message is a request (``Q=0``) and to indicate that recursion is desired (``RD=1``). Finally, we declare that we will be sending a single question in this request. Note that all of the numeric values are set using the ``htons()`` and ``htonl()`` standard C functions to ensure that the values in the datagram will be in the correct byte order.

.. _cl4-17:

.. codeinclude:: Sockets/CodeListing-4-17.c
   :linenos: true

`Code Listing 4.18 <#cl4-18>`_ illustrates the initial steps for setting up the question field. The
length of this field is not fixed, as it depends on the length of the domain name being translated.
As such, the ``dns_question_t`` type does not contain the full contents of the question itself,
using a pointer to the name field within the program instead. For this scenario, we are only
requesting an Internet address record, so we set the ``QTYPE`` to 1 (``A``) and ``QCLASS`` to 1 (``IN``).

.. codeinclude:: Sockets/CodeListing-4-18.c
   :linenos: true

Recall the domain name formatting in `Table 4.7 <#tbl4-7>`_ and `Table 4.9 <#tbl4-9>`_. Given a human
readable domain name, such as ``www.charity.org``, the string is broken apart into distinct fields
based on the dot; in this case, the three fields are ``"www"``, ``"charity"``, and ``"org"``. Within
the DNS question, each field is preceded by a one-byte value that indicates the length of the field.
The name is considered terminated once the null-byte is used to indicate a zero-length field. `Code
Listing 4.19 <#cl4-19>`_ shows an algorithm to convert a human readable name into the DNS question
format. The code starts by copying the hostname into the second byte of the space allocated for the
name; the reason for this is to leave one byte of space for the length of the first field (which
will be 3 for ``"www"``), which will be determined later. Throughout the rest of the algorithm the
prev pointer is used to keep track of the location of the byte where the current field's length will
be stored. As such, prev is initialized to the first byte of the space for the name.

.. codeinclude:: Sockets/CodeListing-4-19.c
   :linenos: true

When the hostname is copied into the space for the question, the string still contains the dot characters. In the DNS question format, these dots are replaced by the lengths of the field that follows. Returning to the example of ``www.charity.org``, the first dot should be replaced by 7, indicating the length of the field ``"charity"``. The for-loop in `Code Listing 4.19 <#cl4-19>`_ replaces the dots with the field name, by keeping prev pointing to the location of the dot preceding the current field. As such, once another dot is encountered, the code can update the byte where the previous dot is stored with the length of the field that just ended. The count variable is then reset to 0 (starting to count the length of a new field), and prev is updated to point to the new dot. When the loop ends, prev is still pointing to the location of the last dot, so its value can be modified with the length of the last field.

.. topic:: Bug Warning

   .. figure:: Images/CSF-Images-BugWarning.png
      :align: left
      :width: 90%
      :alt: Decorative bug warning

   The correctness of `Code Listing 4.19 <#cl4-19>`_ relies on correct handling of two common mistakes
   with pointers. First, it is important to distinguish between updating where in memory the prev
   pointer is pointing ``(prev = query + i + 1)`` and updating the value stored at that memory
   location ``(*prev = count)``. Typos involving the ``*`` are notorious sources of bugs with
   pointers. The second critical dependency is the use of ``calloc()`` in `Code Listing 4.18
   <#cl4-18>`_ instead of ``malloc()``. Using ``calloc()`` initializes the space that question.name
   points to with all zeroes. Consequently, we do not need to explicitly null-terminate the string,
   because there is already a zero there. Since ``malloc()`` does not guarantee initialization of the
   allocated memory space, the byte that indicates the zero-length field might not actually store 0.
   This could lead to incorrect behavior in the DNS processing, including buffer overflows at either
   the client or server.

Once the header and question fields have been constructed, all that remains is to assemble these
bytes into a packet and send the request through the UDP socket. `Code Listing 4.20 <#cl4-20>`_
illustrates this procedure. First, the total packet length needs to be determined. DNS headers are
fixed size, but the questions are not. The length of the question is based on the extended length of
the hostname (including the byte for the first field's length and the final null-terminating byte).
The question also contains two 16-bit values to indicate the ``QTYPE`` and ``QCLASS``. Once the size
is determined and the space is dynamically allocated, the code concatenates all fields as necessary.
The header is copied in first, followed immediately by the ``QNAME``, with the ``QTYPE`` and
``QCLASS`` at the end. Since DNS is based on UDP for transport, the code must use ``sendto()`` to
deliver the message to the socket.

.. codeinclude:: Sockets/CodeListing-4-20.c
   :linenos: true

Processing DNS Query Responses
------------------------------

To receive the response from the DNS server, `Code Listing 4.21 <#cl4-21>`_ starts by allocating and
clearing the contents of a 512-byte buffer in memory. The length of this buffer can be hard-coded in
this way, as the DNS specification mandates a maximum of 512 bytes for all messages. The actual
length of the received data is set when ``recvfrom()`` retrieves the response from the socket.

.. codeinclude:: Sockets/CodeListing-4-21.c
   :linenos: true

The response from the server (assuming the request is successfully processed) would consist of the
fixed-size header, a question field identical to that sent in the request, and an answer containing
the information from a resource record. The structure of the answer depends on several factors,
including the IP version (IPv4 or IPv6) and the type of record requested. That is, the responses for
address (``A``), namespace (``NS``), or canonical name (``CNAME``) records vary in structure. In
this scenario, we are requesting an IPv4 address, so the bytes in the request would match the
following ``struct`` definition.

.. codeinclude:: Sockets/DNSRecord.c
   :linenos: true

.. topic:: Bug Warning

   .. figure:: Images/CSF-Images-BugWarning.png
      :align: left
      :width: 90%
      :alt: Decorative bug warning

   The use of ``__attribute__((packed))`` in this ``struct`` declaration is critical to tell the
   compiler not to re-order the fields of the ``struct`` within the program. When reading data from
   the network, the bytes will occur in a particular order. When we use a ``struct`` to impose a
   logical meaning on those bytes in a program, we would expect the interpretation to look like
   this:

   .. figure:: Images/CSF-Images.4.0.1.png
      :align: center
      :width: 50%
      :alt: DNS structures are packed in a way that does not preserve word alignment

   However, compilers routinely re-order the fields in a ``struct`` to preserve *word alignment*,
   trying to group the bytes into chunks of 32 bits as much as possible. In this case, many compilers
   would swap the ``ttl`` and ``length`` fields, which would impose the wrong structure on the
   sequence of bytes received from the network:

   .. figure:: Images/CSF-Images.4.0.2.png
      :align: center
      :width: 50%
      :alt: Failing to declare a DNS record ``struct`` as packed can mislabel bytes due to word alignment

`Code Listing 4.22 <#cl4-22>`_ shows how the client can take the received response and interpret it
correctly for an IPv4 A record. By casting the response as a ``dns_header_t *`` variable, the code
can refer to the fields within the header based on the struct declaration. By applying the ``0xf``
bit mask, we can examine just the ``RCODE`` field of the flag to detect if an error occurs. If the
``RCODE`` is 0, then the request was processed correctly. Next, we need to traverse through the
question field, which begins with the variable-length ``QNAME``. The ``start_of_name`` pointer is
created to keep track of where the name starts. Each iteration of the loop determines where the next
field length byte will occur and replaces it with a dot, while calculating the total length of the
name.

.. codeinclude:: Sockets/CodeListing-4-22.c
   :linenos: true

Once we have determined the total length of the domain name in the question field, we can skip
directly to the resource records in the answer. Immediately after the while loop in `Code Listing
4.22 <#cl4-22>`_, the ``field_length`` pointer will be pointing to the null byte at the end of the
name. The records begin five bytes later, after the null byte, the ``QTYPE``, and the ``QCLASS``
fields. Casting the remaining bytes as a ``dns_record_a_t *`` allows `Code Listing 4.23 <#cl4-23>`_
to treat this data as an array of records. The fields of these records can then be cast using the
``struct`` definition from above.

.. codeinclude:: Sockets/CodeListing-4-22.c
   :linenos: true

The Extended Example for Chapter 5 combines all of the preceding code segments, along with some
additional statements for printing, into a single program to run as a basic DNS client. If this
program is compiled into the current directory as an executable called ``dns``, the output would
look like the following when querying the address ``example.com``. Note that this example only works
with some domain names, as our basic client only supports a limited subset of the required
functionality as defined in RFC 1034 and RFC 1035.

.. codeinclude:: Sockets/DNS.txt

.. [#f27] The domain name and IP address for ``www.charity.org`` are fictional and provided for
   illustrative purposes only. The addresses 198.41.0.4 and 199.19.56.1 are the real addresses for the
   root and .org TLD name servers, however.

.. [#f28] The Internet Assigned Name Authority (IANA) is one portion of ICANN. IANA maintains
   ``example.com`` specifically as a public resource for illustrating DNS functioning. 

.. [#f29] The DNS specification prepends a ``"Q"`` to the beginning of field names to indicate that
   the field is for a query, even though the distinction has no practical impact for basic queries.
   Hence, the reader should treat ``NAME`` and ``QNAME `` as the same, likewise for ``CLASS`` and
   ``QCLASS``, and so on.

.. [#f30] Linux contains similar structs in ``<arpa/nameser.h>`` and ``<arpa/nameser_compat.h>``,
   but they are more complex than shown here. For instance, the Linux version contains names to access
   the individual bits of the ``flags`` field.

.. [#f31] By using OpenDNS in this scenario, we can illustrate the full process of the network
   request, including setting up the UDP socket with an IP address that is functional as of this
   writing. OpenDNS also provides a number of other benefits, such as increased privacy and security
   services. For more information, consult their site at ``https://www.opendns.com``.

.. avembed:: Exercises/Sockets/AppUDPSumm.html ka
   :module: UDPSockets
   :points: 1.0
   :required: True
   :exer_opts: JXOP-debug=true&amp;JOP-lang=en&amp;JXOP-code=java
   :long_name: UDP socket programming questions
   :threshold: 5

