<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc SYSTEM "D:/Program%20Files/XML%20Copy%20Editor/dtd/rfc2629.dtd" [
  <!ENTITY rfc2119 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml'>
  <!ENTITY rfc1033 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.1033.xml'>
  <!ENTITY rfc1034 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.1034.xml'>
  <!ENTITY rfc1035 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.1035.xml'>
  <!ENTITY rfc2136 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2136.xml'>
  <!ENTITY rfc2181 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2181.xml'>
  <!ENTITY rfc2308 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2308.xml'>
  <!ENTITY rfc2845 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2845.xml'>
  <!ENTITY rfc2930 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2930.xml'>
  <!ENTITY rfc3425 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.3425.xml'>
  <!ENTITY rfc2119 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml'>
  <!ENTITY rfc4033 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.4033.xml'>
  <!ENTITY rfc4034 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.4034.xml'>
  <!ENTITY rfc4035 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.4035.xml'>
  <!ENTITY rfc5155 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.5155.xml'>
  <!ENTITY rfc6891 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.6891.xml'>
]>
<?rfc compact="yes" ?>
<rfc category="std" ipr="trust200902" docName="draft-dickson-dnsop-spartacus-system-00">
<?rfc toc='yes'?>
<front>

    <title abbrev="DNS Gateway System">
System to transport DNS over HTTP using JSON
</title>

    <author initials="B.P." surname="Dickson" fullname="Brian Dickson">
      <address>
        <postal>
          <street>12047B 36th Ave NE</street>
          <city>Seattle</city>
          <region>wA</region>
          <code>98125</code>
        </postal>
        <email>brian.peter.dickson@gmail.com</email>
      </address>
    </author>

    <date month="October" year="2014"/>
    <area>Internet</area>
    <workgroup>dnsop</workgroup>
    <keyword>
DNSOP
</keyword>
    <abstract>
      <t>
    This is the SPARTACUS DNS gateway system. It is designed to facilitate the transport of DNS messages opaquely, across problematic sections of the Internet. It uses JSON encoding, and HTTP(S) as the protocol for transport.
    <vspace blankLines="1" />
    The main criteria of SPARTACUS is that it preserve DNS messages verbatim, and that only properly formatted DNS messages are passed.
    <vspace blankLines="1" />
    There are two modes (so far) defined: DNS forwarder (dns clients point to a local gateway, which forwards to a remote gateway for sending to a DNS resolver); and transparent proxy (DNS packets are intercepted, passed to a local gateway, which sends them to the remote gateway, with original destination IP address etc. encoded, and used by the remote gateway as the destination).
    <vspace blankLines="1" />
    DNS messages are NAT-friendly, so changes to IP or UDP headers do not impact them. Thus, SPARTACUS does not interfere with TSIG, SIG(0), or Eastlake Cookies.
    <vspace blankLines="1" />
    This document describes the system, the components, and behavior, with examples.  </t>
    </abstract>
    <note title="Author's Note">
    <t>
      Intended Status: Proposed Standard.
    </t>
    </note>
  </front>
<middle>
<section title="Introduction">
<t>
    DNS (The Domain Name System) has been deployed since the 1980's <xref target="RFC1033"/><xref target="RFC1034"/><xref target="RFC1035"/>.
    Since that time, some of the original Resource Record types have been made officially obsolete <xref target="RFC3425"/>.
    Some elements have been clarified <xref target="RFC2181"/><xref target="RFC2308"/>.
    New Resource Records have been added <xref target="RFC2136"/><xref target="RFC2845"/><xref target="RFC2930"/><xref target="RFC6891"/>.
    New definitions of bits in the header have arisen, in part due to DNSSEC's AD and CD bits <xref target="RFC4033"/><xref target="RFC4034"/><xref target="RFC4035"/><xref target="RFC5155"/>.
    <vspace blankLines="1" />
    This has resulted in now-outdated implementations of stateful devices (e.g. devices doing either NAT or packet inspection) interfering
    with end-to-end communication between DNS speakers. Old devices or implementations reject DNS packets that include these newer capabilities, features, or format changes.
    <vspace blankLines="1" />
    At the same time, there has arisen a variety of other devices and systems whose deliberate function is to block, capture, or modify DNS traffic, for profit or for ideological reasons. Examples include hotel wifi systems, ISPs, and state actors.
    <vspace blankLines="1" />
    Owing to the stateless nature of DNS over UDP, it is not possible to distinguish between deliberate and accidental sources of DNS interference.
</t>
<section title="Problem Statement">
    <t>
    There is a need to provide ways of supporting incremental deployment of new DNS features, in such a way as to prevent deliberate and/or accidental interference in the communication between DNS speakers.
    <vspace blankLines="1" />
    For example, DNS speakers could communicate over protected channels and with data integrity validation via DNSSEC. The foremost limitation is that the communication be over any other port/protocol combination than UDP port 53. Ideally, the choice should be an encoding that is compatible with whatever port/protocol combination is selected (versus overloading the port/protocol with incompatible payloads).
    <vspace blankLines="1" />
    There is a further need for the communications channel(s) to be standardized, and to not introduce further interoperability problems at the DNS protocol level. Independent implementations need to interoperate completely, to avoid merely pushing the compatibility problem around.
    <vspace blankLines="1" />
    In order to solve these problems (individually and/or collectively), the SPARTACUS system has been developed.
    </t>
</section>
<section title="Rationale">
<t>
   SPARTACUS (Secure, Private Aparatus for Resolution Transported Across Constraining and/or Unmaintained Systems),
   is a system for encoding and decoding DNS messages (the DNS payload of UDP or TCP packet streams).
   <vspace blankLines="1" />
   The SPARTACUS system consists of bidirectional DNS gateways for transporting DNS over HTTP(S) using a JSON encoding scheme.
   This is intended to create "bridges" between DNS speakers; perhaps a better analogy would be "ferries",
   as there is no requirement for a tightly bound relationship between individual Client nodes and Server nodes.
   <vspace blankLines="1" />
   Standardizing the JSON encoding used by SPARTACUS, is intended to ensure
   a greater likelihood of compatible, interoprable implementations.
   <vspace blankLines="1" />
   The goal is to transport DNS messages from any Client implementation
   to any Server implementation.
   <vspace blankLines="1" />
   Each gateway must be liberal in what it accepts (any valid DNS message conforming to the relevant RFCs, regardless of DNS implementation)
   and conservative in what it sends (all packets must parse correctly as DNS messages).
   In order to ensure forward compatibility, unknown Types and (in the case of OPT) sub-types, MUST be accepted and transported.
   <vspace blankLines="1" />
   DNS messages MUST traverse the encode/decode process unaltered.
   The round-trip is designed to, and MUST be implemented to, preserve the entire DNS message's fidelity.
   This means a 1:1 binary match between input, encoding, decoding, and output.
   The lengths MUST match, and messages MUST be identical, bit for bit.
   <vspace blankLines="1" />
   A secondary objective of the encoding in JSON is the use of the same names for data elements and structures
   as in the DNS RFCs. The idea is to provide human-readable JSON encodings,
   for easier diagnostics during development, and when investigating operational issues.
</t>
</section> 
<section title="Related Work">
<t>
A variety of other work exists, and provided inspiration for the SPARTACUS work. This includes web/JSON DNS portals, for providing DNS query responses in JSON format, often with a "looking glass" functionality.
FIXME format this list appropriately and decorate with words.
END FIXME
<list style="symbols">
<t>Multi-location DNS Looking Glass - Tool for performing DNS queries via RESTful interface in multiple locations, returning results in JSON format</t>
<t>DNS Looking Glass - Tool for performing DNS queries via RESTful interface, returning results in JSON format</t>
<t>DNS JSON - Source code project from circa 2009, partially developed but incomplete/abandoned</t>
<t>DNSSEC-trigger<xref target="trigger"></xref> - embedded control function in NLnetlabs' Unbound resolver, for attempting DNS queries over TCP port 80 when DNSSEC problems are encountered</t>
<t>Various other web-based DNS lookup tools</t>
</list>
</t>
<section title="Comparison">
<t>
There has been at least one previous effort to develop code for a DNS-JSON encoding, which appears to have been abandoned after one-way encoding was done, circa 2009.
The project focused on presenting results to DNS queries in JSON format, with an intention to create a client gateway, which never materialized.
The project can be found in two places (<xref target="JPF_jsondns"></xref> and <xref target="jsondns.org"></xref>).
One major difference is that DNS query response status is converted to HTTP error codes, rather than being embedded in the JSON answer.
This makes it unsuitable for bidirectional use. Only a few DNS type codes were implemented.
<vspace blankLines="1" />
Another DNS JSON tool <xref target="fileformat.info"></xref>, similarly focuses only on answers, with a limited number of type codes.
<vspace blankLines="1" />
Yet another tool for looking up DNS via HTTP with JSON responses is the "dnsrest" <xref target="restdns.net"></xref>.
It too focuses only on answer values, and is similarly not able to fully produce results that can be turned back into DNS answer packets.
<vspace blankLines="1" />
The "DNS Looking Glass" <xref target="bortzmeyer.org"></xref>, is primarily designed for returning DNS answer data.
As such, it lacks encoding suitable for a bidirectional scheme.
It is primarily focused on XML output, with JSON output organized around DNS resolution meta-data, plus answer data in a generic schema.
(The schema itself is described in <xref target="draft-bortzmeyer-dns-json"></xref>.)
<vspace blankLines="1" />
The "Multilocation DNS Looking Glass" <xref target="dns-lg.com"></xref>, uses a RESTful query mechanism of "node/qname/qtypename" to request the looking glass (LG) to perform a DNS lookup for the qname and qtype, and returns the response in a JSON format.
The JSON format is generic, encapsulating all types as string data in presentation format, with a generic label of "rdata".
This does not facilitate decoding easily, as the JSON scheme provides no information for parsing the rdata field.
The type (qtype for the query, or type for answer/authority/additional) is in string (symbolic) form, and the elements are objects and thus in unordered lists.
The JSON scheme is fine for one-way encoding for human readability, but not suitable for two-way conversion back into DNS.
<vspace blankLines="1" />
DNSSEC-trigger<xref target="trigger"></xref> can only be used in environments that use NLnetlabs' Unbound resolver, or where Unbound can be deployed as a replacement for existing recursive resolvers and/or stub resolvers.
<vspace blankLines="1" />
A variety of other web lookup tools exist, predominantly producing DNS validation (zone structure and hierarchy), maps, meta-data, or literal output from the 'dig' tool, in formats as varied as the purposes of the tools.
Dig output, while being reasonably deterministic, is not sufficiently well-formed as to facilitate "screen scraping" as a parsing method.


</t>
</section>
</section> 
</section> 
<section title="Requirements">
<t>
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
      NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and
      "OPTIONAL" in this document are to be interpreted as described in
      <xref target="RFC2119" />.
</t>
</section>
<section title="System Overview">
<t>
The SPARTACUS system is designed to improve the reliability and security of the DNS system, by providing the means to transport DNS traffic across segments of the Internet. The goal is to bypass problem areas which interfere with DNS communications, regardless of root cause of the interference.
   <vspace blankLines="1" />
Some familiarity with the DNS protocol is assumed.
</t>
<section title="System Elements">
<t>
The particular system elements used will differ, based on the mode of operation of the Client.
Clients may request the use of particular resolvers via additional intra-element signalling.
</t>
<section title="Node Types">
<t>
Base node types are the following:
<list style="symbols">
<t>Standalone SPARTACUS Client forwarder</t>
<t>Transparent SPARTACUS proxy Client</t>
<t>Standalone SPARTACUS Server</t>
<t>Apache module-based SPARTACUS Server</t>
<t>Stub resolver</t>
<t>External recursive resolver</t>
<t>Client-side recursive resolver</t>
<t>External authority server</t>
</list>
    <vspace blankLines="1" />
Future node types are expected to include:
<list style="symbols">
<t>Browser-integrated SPARTACUS client and stub resolver</t>
<t>Mobile-device SPARTACUS client and stub resolver (with exposed getdns API)</t>
<t>SMTP-integrated SPARTACUS client and stub resolver</t>
</list>
</t>
</section>
</section>
<section title="System Modes">
<t>
The system has two modes of operation:
<list style="symbols">
<t>DNS Forwarder - an opaque mode of operation, the Client/Server pair act collectively as a single DNS forwarder.</t>
<t>Transparent Proxy - In this mode, regular DNS traffic is diverted by unspecified means to the SPARTACUS Client.</t>
</list>
Additional intra-element signalling facilitates Clients requesting particular resolvers' (recursive or authoritative) use.
</t>
<section title="Details on DNS Forwarder mode">
<t>
The Server is configured to use a particular DNS recursive resolver,
with the optional ability to support Client-requested resolver(s) via in-band signaling.
If present, the Client-requested resolver IP address is passed as an EDNS OPT value.
The Server, if it is configured to honor requested resolvers, uses this IP address instead of the default.
    <vspace blankLines="1" />
<figure anchor="figure1">
<preamble>Example: Problem caused by firewalls that do not support DNSSEC:</preamble>
<artwork><![CDATA[
+------+    +--------------+            +----------+
|      |    |              |  Blocked   |          |
| Stub +--> | Old Firewall +----+X+---> | Resolver |
|      |    | (no DNSSEC)  |  Packets   |          |
+------+    +--------------+            +----------+
]]></artwork></figure>
<figure anchor="figure2">
<preamble>Example: How the stub client sees the SPARTACUS Client/Server pair, in the opaque forwarder configuration:</preamble>
<artwork><![CDATA[
+------+    +----------------------------------+      +----------+
|      |    |                                  |      |          |
| Stub +--> |            Forwarder             +----> | Resolver |
|      |    |           with DNSSEC            |      |          |
|      | <--+                                  | <----+          |
+------+    +----------------------------------+      +----------+
]]></artwork></figure>
<figure  anchor="figure3">
<preamble>Example: How the Client/Server pair actually operates:</preamble>
<artwork><![CDATA[
+------+     +--------+               +--------+      +----------+
|      |     |        |               |        |      |          |
| Stub +---> | Client +-------------> | Server +----> | Resolver |
|      | DNS |        | JSON/HTTP(S)  |        | DNS  |          |
|      | <---+        | <-------------+        | <----+          |
+------+     +--------+               +--------+      +----------+
]]></artwork></figure>
<figure  anchor="figure4">
<preamble>Example: How the Client/Server bypass the old firewall:</preamble>
<artwork><![CDATA[
+------+   +--------+  +--------------+  +--------+   +----------+
|      |   |        |  | Old Firewall |  |        |   |          |
| Stub +-> | Client +------------------> | Server +-> | Resolver |
|      |   |        |  |  (bypassed)  |  |        |   |          |
|      | <-+        | <------------------+        | <-+          |
+------+   +--------+  +--------------+  +--------+   +----------+
]]></artwork></figure>
</t>
</section>
<section title="Details on Transparent Proxy mode">
<t>
Transparent Proxy mode supports transport of stub to recursive traffic (all with the same destination IP address).
   <vspace blankLines="1" />
Transparent Proxy mode also supports use by a recursive resolver, to handle recursive-to-authoritative traffic (with different destination IP addresses per query).
   <vspace blankLines="1" />
From the perspective of the DNS client (stub or recursive), it appears that the DNS query packet went to some IP address, and the reply came back directly.
<figure  anchor="figure5">
<artwork><![CDATA[
+----------+                                      +--------------+
|          +------------------------------------> |              |
|   Stub   |                                      |   Recursive  |
|  src=SR  | DNS UDP/53 SR<->RR                   |    dst=RR    |
|          |                                      |              |
|          | <------------------------------------+              |
+----------+                                      +--------------+
]]></artwork></figure>
<figure  anchor="figure5a">
<artwork><![CDATA[
+-----------+                                                     
|           +-----------------------------------> +--------------+
|           |                                     | Authority #1 |
|           | <-----------------------------------+   dst=AR_1   |
|           |                                     +--------------+
|           +-----------------------------------> +--------------+
| Recursive |                                     | Authority #2 |
|  src=RR   | <-----------------------------------+   dst=AR_2   |
|           |                                     +--------------+
|           |                                          ...        
|           +-----------------------------------> +--------------+
|           |                                     | Authority #N |
|           | <-----------------------------------+   dst=AR_N   |
+-----------+                                     +--------------+
                DNS UDP/53 RR<->AR_N (N=1,2,...)                  
]]></artwork></figure>
   <vspace blankLines="1" />
In both use cases, the original IP destination is encoded as an EDNS OPT value, and the DNS message (encoded as JSON) is sent to the SPARTACUS Server.
The Server sends the DNS message to the original IP destination, with the SPARTACUS Server's IP address as the source.
The resulting answer DNS message is sent to the Client, which changes the reply source IP address to the original destination IP address.
<figure  anchor="figure6">
<artwork><![CDATA[
+-----------+            +-------+  +---------+   +---------------+
|           |            |       |  |         |   |               |
|           +----------> | Trans.|  | Server  +-> | Authoritative |
|           |            | Proxy |  | Gateway |   |  Resolver #1  |
|           | <----------+  TP   |  |   SG    | <-+     AR_1      |
|           |            +-----+-+  +------+--+   +---------------+
|           | DNS UDP/53       |           |         DNS UDP/53    
| Recursive | RR <-> AR_1    ^ v        ^  |         SG <-> AR_1   
| Resolver  |                |          |  |                       
|    RR     |            +---+-----+    |  |                       
|           |            | Client  +----+  |   TCP/80 (or /443)    
|           |            | Gateway |       | JSON (EDNS: dst=AR_1) 
|           |            |   CG    | <-----+      CG <-> SG        
+-----------+            +---------+                               
]]></artwork></figure>
   <vspace blankLines="1" />
The only practical difference is that some intermediate devices see JSON/HTTP(S) instead of DNS/UDP traffic.
For some of those devices, this is in fact the purpose of SPARTACUS - preventing those devices from inspecting the DNS traffic in a problematic manner.
</t>
</section>
</section>
<section title="Interoperability">
<t>
The purpose of this document is to ensure that independent implementations of Client(s) and Server(s) can interoperate, so long as each is permitted to interoprate with the other.
   <vspace blankLines="1" />
It is not required that Servers be operated in a completely "open" manner.
However, the more open Servers there are, the greater the benefit.
Like any web-based service, care should be given towards managing available resources on a Server.
In all likelihood, this resource management may be most effectively handled via the web server's own service management system.
</t>
<section title="In-scope and out-of-scope">
<t>
The following items are out-of-scope, from an interoperability standpoint.
   <vspace blankLines="1" />
This means that individual implementations may make independent design decisions, without impacting interoperability.
<list style="symbols">
<t>Choice(s) of default resolver (on Server)</t>
<t>Server-side DNS retry and time-out values</t>
<t>How Client(s) select Servers</t>
</list>
   <vspace blankLines="1" />
The following items are in-scope, from an interoperability standpoint.
<list style="symbols">
<t>JSON encoding</t>
<t>How to signal non-support of requested resolver(s)</t>
<t>How to signal "no response" (timeout) on Server-resolver traffic</t>
<t>Signalling/encoding of default,requested, and actually-used resolvers</t>
<t>Stripping of EDNS OPT private values</t>
<t>Stripping of synthesized EDNS OPT record</t>
</list>
The following items are optional, from an interoperability standpoint.
<list style="symbols">
<t>Whether and how to do edns-client-subnet (on Client)</t>
<t>Whether to use TLS (HTTPS) on Client-Server traffic</t>
<t>Whether to honor requested resolvers (on Server)</t>
<t>Whether to support Transparent Proxy mode (on the Client)</t>
<t>Whether to do DNSSEC validation</t>
<t>Whether to do PKI validation of SSL certificates (if HTTPS is used and CA-issued certs used)</t>
<t>Whether to do DANE validation of SSL certificates (if HTTPS is used and TLSA records exist)</t>
<t>Whether IPv4 or IPv6 is supported</t>
</list>
</t>
</section>
</section>
</section>
<section title="Interactions and Behavior">
<t>
The Client Gateway needs to make informed decisions about Server Gateways to use. Client Gateways may use pre-configured (static) gateways, or may employ any number of strategies for selection of Server Gateways.
   <vspace blankLines="1" />
In order to enble Client-controlled Server Selection, each Server Gateway needs to advise the Client about default and actual DNS Servers used.
The Client optionally requests DNS Server(s) that the Server should use.
If present, the Server includes that in the response.
   <vspace blankLines="1" />
The SPARTACUS client/server interaction occurs over TCP rather than UDP. As such, other than TCP-based failures (RST aka "reset" for example), every query MUST get a response (owing to the HTTP POST standards).
   <vspace blankLines="1" />
Since the Server Gateway is performing DNS resolution using UDP transport, it is possible that network packet loss may occur, resulting in unanswered queries.
   <vspace blankLines="1" />
Also, there are reasons other than network-based packet loss that can result in unanswered queries.
DNS resolvers must attempt to infer what causes queries to not be answered.
   <vspace blankLines="1" />
It is also possible that various other failure modes could occur, which need to be handled on the basis of the nature of the failure.
   <vspace blankLines="1" />
Each of these is addressed in separate sections below.
</t>
<section title="DNS Gateway Encodings">
<t>
The three DNS Server values (default, requested, actual) are communicated via EDNS OPT type-length-value (TLV) tuples, using three distinct types.
Pre-standard experimental values are presently being used.
IANA will need to assign permanent OPT Type values for these three type codes.
   <vspace blankLines="1" />
In order to ensure that the EDNS OPT record is only returned to the original DNS client if it existing in the query, it is necessary to identify cases where the DNS Server value encoding resulted in a "new" OPT record, rather than being added to an existing record.
In such cases, an additional OPT TLV type is required, and is added to the OPT record.
A fourth OPT Type value needs to be assigned by IANA for this purpose.
   <vspace blankLines="1" />
The new OPT codes are used to enable the Client and Server to maintain all communication details inside the DNS message itself.
This simplifies the design, implementation, and operation of Clients and Servers, and ensures forward/backward compatibility.
OPT codes specific to the Client-Server communication MUST be removed prior to forwarding of DNS messages to DNS Clients and Servers.
If the EDNS OPT RR is synthesized (added to the DNS message), it MUST be removed.
</t>
</section>
<section title="UDP Packet Loss">
<t>
In cases where the Server Gateway did not get a response from the DNS Server, it needs to signal this back to the client.
It needs to do this so that the proper Client state is established.
This prevents time-out based (undefined) behavior on the Client from being triggered.
The Server needs to "pass along" packet loss status to the Client to trigger well-defined Client behavior.
   <vspace blankLines="1" />
The mechanism is to use a Private EDNS OPT type/length/value (TLV), with the original Question echoed back (to associate with the Query).
When receiving this TLV, the Client will treat this as a lost UDP packet, and MUST NOT send back any UDP packet.
The UDP client is responsible for handling this lost UDP packet, per the DNS protocol.
</t>
</section>
<section title="Malformed UDP response">
<t>
The malformed UDP packet may not be legitimate. To be conservative, this condition is signaled back to the client, and the (actual) received UDP packet is rejected/dropped. This is treated by the DNS client as a lost UDP packet.
</t>
</section>
<section title="DNSSEC Validation Failure">
<t>
If DNSSEC validation fails, the presumption needs to be made that the failure is deliberate. The DNSSEC standards call for "SRVFAIL" responses, so that is what a compliant implementation MUST return to the UDP client.
   <vspace blankLines="1" />
If the Client and/or Server does DNSSEC Validation, it MUST correctly implement Validation signalling via the AD and CD bits.
   <vspace blankLines="1" />
In other words, it MUST return the answer regardless of Validation if the CD bit is set, and it MUST set the AD bit if Validation succeeds, regardless of the presence and/or state of EDNS bit DO.
</t>
</section>
</section>
<section title="Client-Server Selection and Topology Examples">
<t>
<figure  anchor="figure8">
<artwork><![CDATA[
                    +-----------+                    
                    |           |                    
               +--> | Server    +--+                 
+-----------+  |    | Gateway 1 |  |                 
|  Client   |  |    +-----------+  |    +-----------+
|  Gateway  +--+    +-----------+  +--> |           |
|           |       |           |       | Recursive |
|  Selects  +-----> | Server    +-----> |    DNS    |
|  Random   |       | Gateway 2 |       |   Server  |
|  Server   +--+    +-----------+  +--> |           |
|  Gateway  |  |    +-----------+  |    +-----------+
+-----------+  |    |           |  |                 
               +--> | Server    +--+                 
                    | Gateway 3 |                    
                    +-----------+                    
]]></artwork></figure>
<xref target="figure8"/> shows the same Recursive DNS Server being used, via multiple Server Gateways. There are several benefits to doing this; they include distributing load among multiple Server Gateways, and reducing the amount of DNS traffic going via any single Server Gateway. This limits the impact of the compromise of any single Server Gateway, or of any single Server Certificate compromise.
<figure  anchor="figure9">
<artwork><![CDATA[
                           +--------+                              
                           |        |                              
                   +-----> | Server |                              
+-----------+      |       | GW 1   |                 +-----------+
|  Client   |  +---+----+  +------+-+   +--------+    |           |
|  Gateway  |  |        |         |     |        |    |           |
|           |  | Server | <--+    +---> | Server +--> |           |
|  Selects  |  | GW 2   |    |          | GW 4   |    |    DNS    |
|  Random   |  +--------+  +-+------+   +--------+    |   Server  |
|  Server   |              |        |                 |           |
|  Gateway  |              | Server |                 |           |
|           +------------> | GW 3   |                 |           |
+-----------+              +--------+                 +-----------+
]]></artwork></figure>
<xref target="figure9"/> illustrates a path where more than one Server Gateway is traversed during resolution.
The objective here is to disassociate the IDENTITY of the client from the CONTENT of the query/answer.
The association is only made directly on the first Server Gateway (and only with respect to the Client Gateway).
The actual association of the source UDP client is only done on the Client Gateway itself, which may or may not provide further privacy.
Since there is more than one Server-Server hop, this significantly reduces the ability to infer associations between Query/Response and Client Gateways.
    <vspace blankLines="1" />
It should be noted that this looks very much like TOR (The Onion Router), applied to JSON-encoded UDP DNS traffic. There is a proposal for DNS privacy enhancements that applies a similar techique, directly on UDP-based DNS queries/answers. FIXME add xref here to reference to the appropriate Internet Draft. END FIXME
<figure  anchor="figure10">
<artwork><![CDATA[
+---------------+ +--------+ +--------+ +------------+   +----------+
|    Client     | | WWW/GW | | WWW/GW | |            |   |          |
|    Gateway    | | Server | | Server | | Web Server |   |          |
|               | | GW 3   | | GW 4   | |            |   |          |
|    Selects    | +--------+ +--------+ +----------+ |   |   DNS    |
|     Among     |                       | Gateway  | |   |  Server  |
|  Most Recent  |  DNS traffic mingled  | Server   | |   |          |
|   Web Server  |   with web traffic    | Module   +---> |          |
|    Gateways   +---------------------> |  GW 2    | |   |          |
+---------------+    (or encrypted)     +----------+-+   +----------+
]]></artwork></figure>
<xref target="figure10"/> illustrates one query/response when the client is attempting to use something similar to steganography to preserve privacy.
In this context, the privacy against passive monitoring is achieved by using un-blocked web servers which are also Server Gateways.
A MitM adversary cannot easily block this traffic without blocking the entire site, or by inspecting every flow to/from the site.
A passive observer would similarly need to inspect all flows to find the embedded, encoded DNS traffic.
The DNS traffic would be nearly indistinguishable from regular HTTP traffic.
    <vspace blankLines="1" />
Note that the use of TLS to protect the Client-Server traffic would make it impossible to distinguish the DNS traffic from the other web trafficin this situation. Combining this "tag-along" with TLS provides both strong privacy and strong security.
</t>
<section title="Mixed Traffic Walk-Through">
<t>
Suppose a client were to visit web sites "a" through "j" sequentially, i.e. a,b,c,d,e,f,g,h,i,j.
Suppose some of those were also Server Gateways, represented by upper case (vs lower case for web sites without Server Gateway capabilities).
Thus the sequence would be A,b,C,D,e,f,g,H,I,j.
If the Client Gateway chose a Server Gateway randomly from among the last four web sites visited, the sequence of events after visiting A through D, would look like:
<list style="symbols">
<t>Select Server from set {A,C,D}, look up "e". Visit "e".</t>
<t>Select Server from set {C,D}, look up "f". Visit "f".</t>
<t>Select Server from set {C,D}, look up "g". Visit "g".</t>
<t>Select Server from set {D}, look up "h". Visit "h".</t>
<t>Select Server from set {D,H}, look up "i". Visit "i".</t>
<t>Select Server from set {H,I}, look up "j". Visit "j".</t>
</list>
    <vspace blankLines="1" />
An observer close to the Client would see traffic within a given time window, only to the same set of Web servers.
An observer close to any of the Web servers would only see traffic from a given client, for a small interval of time after the first visit.
</t>
</section>
</section>
<section title="Security Considerations">
<t>
(None per se.) Need to list considerations etc.
</t>
</section>
<section title="IANA Considerations">
<t>
   This document will eventually contain IANA-specific material.
</t>
</section>
<section title="Acknowledgements">
<t>
To be added later.
</t>
</section>
</middle>
  <back>
    <references title="Normative References">
      &rfc1033;
      &rfc1034;
      &rfc1035;
      &rfc2136;
      &rfc2181;
      &rfc2308;
      &rfc2845;
      &rfc2930;
      &rfc3425;
      &rfc4033;
      &rfc4034;
      &rfc4035;
      &rfc5155;
      &rfc6891;
    </references>
    <references title="Informative References">
    &rfc2119;
    <reference anchor="JPF_jsondns" target="http://github.com/jpf/jsondns">
    <front><title>DNS over HTTP</title><author initials="J" fullname="Joël Franusic"></author><date></date></front>
    </reference>
    <reference anchor="jsondns.org" target="http://jsondns.org/">
    <front><title>Query DNS via REST</title><author initials="J" surname="Franusic" fullname="Joël Franusic"></author><date></date></front>
    </reference>
    <reference anchor="fileformat.info" target="http://www.fileformat.info/tool/rest/dns-json.htm">
    <front><title>DNS in client-side JavaScript</title><author initials="A" surname="Marcuse" fullname="Andrew Marcuse"></author><date></date></front>
    </reference>
    <reference anchor="restdns.net" target="http://restdns.net/">
    <front><title>REST-DNS</title><author fullname="(unknown author)"></author><date></date></front>
    </reference>
    <reference anchor="bortzmeyer.org" target="http://www.bortzmeyer.org/dns-lg.html">
    <front><title>DNS Looking Glass</title><author initials="S" surname="Bortzmeyer" fullname="Stéphane Bortzmeyer"></author><date></date></front>
    </reference>
    <reference anchor="draft-bortzmeyer-dns-json" target="http://tools.ietf.org/html/draft-bortzmeyer-dns-json-01">
    <front><title>DNS in JSON</title><author initials="S" surname="Bortzmeyer" fullname="Stéphane Bortzmeyer"></author><date></date></front>
    </reference>
    <reference anchor="dns-lg.com" target="http://www.dns-lg.com/">
    <front><title>Multilocation DNS Looking Glass</title><author initials="F" surname="Cambus" fullname="Frederic Cambus"></author><date></date></front>
    </reference>
    <reference anchor="trigger" target="http://www.nlnetlabs.nl/projects/dnssec-trigger/">
    <front><title>Dnssec-Trigger</title><author><organization>NLnet Labs</organization></author><date></date></front>
    </reference>
    </references>
  <section title="DNS Message Encoding Examples">
  <t>
  The entire encoding of pairs of DNS messages follows. For each pair,the first is the query, and the second is the response.
  </t>
  <section title="Simple Query/Answer, No EDNS or DNS Server">
  <t>
<figure>
<preamble>Query encoded in JSON:
</preamble>
<artwork><![CDATA[
"PACKET (RFC 1035)" : [
"ROLE" : "client",
"DSIZE" : 26,
"DICTIONARY" : [
"example",
"com",
""
],
"DSIZE2" : 26,
"Header" : [
"ID" : 42,
"HFlags" : [
"QR" : false,
"Opcode" : [ "Query" : 0 ],
"AA" : false,
"TC" : false,
"RD" : true,
"RA" : false,
"Z" : false,
"AD" : false,
"CD" : false,
"RCODE" : [ "NoError (RFC 1035)" : 0 ]

],
"QDCOUNT" : 1,
"ANCOUNT" : 0,
"NSCOUNT" : 0,
"ARCOUNT" : 0
],
"Question" : [
"QUESTION (RFC 1035)" : [
"QNAME" : [ "example.com." : 0 ],
"QTYPE" : [ "A" : 1 ],
"QCLASS" : [ "IN" : 1 ]
]
]
]
]]></artwork>
<postamble>
</postamble>
</figure>
<figure>
<preamble>Response encoded in JSON:
</preamble>
<artwork><![CDATA[
"PACKET (RFC 1035)" : [
"ROLE" : "client",
"DSIZE" : 33,
"DICTIONARY" : [
"example",
"com",
"",
"@0"
],
"DSIZE2" : 33,
"Header" : [
"ID" : 42,
"HFlags" : [
"QR" : true,
"Opcode" : [ "Query" : 0 ],
"AA" : false,
"TC" : false,
"RD" : true,
"RA" : true,
"Z" : false,
"AD" : false,
"CD" : false,
"RCODE" : [ "NoError (RFC 1035)" : 0 ]

],
"QDCOUNT" : 1,
"ANCOUNT" : 1,
"NSCOUNT" : 0,
"ARCOUNT" : 0
],
"Question" : [
"QUESTION (RFC 1035)" : [
"QNAME" : [ "example.com." : 0 ],
"QTYPE" : [ "A" : 1 ],
"QCLASS" : [ "IN" : 1 ]
]
],
"Answer" : [
"RR" : [
"NAME" : [ "example.com." : 0 ],
"TYPE" : [ "A" : 1 ],
"CLASS" : [ "IN" : 1 ],
"TTL" : 5218,
"RDLENGTH" : 4,
"RDATA" : [
"A" : [
"Address" : "93.184.216.119"
]
]
]
]
]
]]></artwork>
<postamble>
</postamble>
</figure>
  </t>
  </section>
  <section title="Simple Query/Answer, EDNS, no DNS Server">
  <t>
<figure>
<preamble>Query encoded in JSON:
</preamble>
<artwork><![CDATA[
"PACKET (RFC 1035)" : [
"ROLE" : "client",
"DSIZE" : 31,
"DICTIONARY" : [
"example",
"com",
"",
""
],
"DSIZE2" : 31,
"Header" : [
"ID" : 42,
"HFlags" : [
"QR" : false,
"Opcode" : [ "Query" : 0 ],
"AA" : false,
"TC" : false,
"RD" : true,
"RA" : false,
"Z" : false,
"AD" : false,
"CD" : false,
"RCODE" : [ "NoError (RFC 1035)" : 0 ]

],
"QDCOUNT" : 1,
"ANCOUNT" : 0,
"NSCOUNT" : 0,
"ARCOUNT" : 1
],
"Question" : [
"QUESTION (RFC 1035)" : [
"QNAME" : [ "example.com." : 0 ],
"QTYPE" : [ "A" : 1 ],
"QCLASS" : [ "IN" : 1 ]
]
],
"Additional" : [
"RR" : [
"NAME" : [ "." : 3 ],
"TYPE" : [ "OPT" : 41 ],
"Field3" : [
"UDPSIZEFIELD" : [
"UDPSIZE" : 1500
]
],
"Field4" : [
"Extended_RCode_Flags" : [
"ERCFlagbits" : [
"RCode" : 0,
"Version" : 0,
"DO" : false,
"Resv" : 0

]
]
],
"RDLENGTH" : 0,
"RDATA" : [
"OPT (RFC 6891)" : [
"TLV_LIST" : [

]
]
]
]
]
]
]]></artwork>
<postamble>
</postamble>
</figure>
<figure>
<preamble>Response encoded in JSON:
</preamble>
<artwork><![CDATA[
"PACKET (RFC 1035)" : [
"ROLE" : "client",
"DSIZE" : 38,
"DICTIONARY" : [
"example",
"com",
"",
"@0",
""
],
"DSIZE2" : 38,
"Header" : [
"ID" : 42,
"HFlags" : [
"QR" : true,
"Opcode" : [ "Query" : 0 ],
"AA" : false,
"TC" : false,
"RD" : true,
"RA" : true,
"Z" : false,
"AD" : false,
"CD" : false,
"RCODE" : [ "NoError (RFC 1035)" : 0 ]

],
"QDCOUNT" : 1,
"ANCOUNT" : 1,
"NSCOUNT" : 0,
"ARCOUNT" : 1
],
"Question" : [
"QUESTION (RFC 1035)" : [
"QNAME" : [ "example.com." : 0 ],
"QTYPE" : [ "A" : 1 ],
"QCLASS" : [ "IN" : 1 ]
]
],
"Answer" : [
"RR" : [
"NAME" : [ "example.com." : 0 ],
"TYPE" : [ "A" : 1 ],
"CLASS" : [ "IN" : 1 ],
"TTL" : 4865,
"RDLENGTH" : 4,
"RDATA" : [
"A" : [
"Address" : "93.184.216.119"
]
]
]
],
"Additional" : [
"RR" : [
"NAME" : [ "." : 4 ],
"TYPE" : [ "OPT" : 41 ],
"Field3" : [
"UDPSIZEFIELD" : [
"UDPSIZE" : 4000
]
],
"Field4" : [
"Extended_RCode_Flags" : [
"ERCFlagbits" : [
"RCode" : 0,
"Version" : 0,
"DO" : false,
"Resv" : 0

]
]
],
"RDLENGTH" : 0,
"RDATA" : [
"OPT (RFC 6891)" : [
"TLV_LIST" : [

]
]
]
]
]
]
]]></artwork>
<postamble>
</postamble>
</figure>
  </t>
  </section>
  <section title="Simple Query/Answer, no EDNS, with DNS Server">
  <t>
<figure>
<preamble>Query encoded in JSON:
</preamble>
<artwork><![CDATA[
"PACKET (RFC 1035)" : [
"ROLE" : "client",
"DSIZE" : 31,
"DICTIONARY" : [
"example",
"com",
"",
""
],
"DSIZE2" : 31,
"Header" : [
"ID" : 42,
"HFlags" : [
"QR" : false,
"Opcode" : [ "Query" : 0 ],
"AA" : false,
"TC" : false,
"RD" : true,
"RA" : false,
"Z" : false,
"AD" : false,
"CD" : false,
"RCODE" : [ "NoError (RFC 1035)" : 0 ]

],
"QDCOUNT" : 1,
"ANCOUNT" : 0,
"NSCOUNT" : 0,
"ARCOUNT" : 1
],
"Question" : [
"QUESTION (RFC 1035)" : [
"QNAME" : [ "example.com." : 0 ],
"QTYPE" : [ "A" : 1 ],
"QCLASS" : [ "IN" : 1 ]
]
],
"Additional" : [
"RR" : [
"NAME" : [ "." : 3 ],
"TYPE" : [ "OPT" : 41 ],
"Field3" : [
"UDPSIZEFIELD" : [
"UDPSIZE" : 1500
]
],
"Field4" : [
"Extended_RCode_Flags" : [
"ERCFlagbits" : [
"RCode" : 0,
"Version" : 0,
"DO" : false,
"Resv" : 0

]
]
],
"RDLENGTH" : 19,
"RDATA" : [
"OPT (RFC 6891)" : [
"TLV_LIST" : [
"TLV" : [
"TYPE" : [ "PrivateType65500" : 65500 ],
"Len" : 13,
"Data" : [
"PrivateType65500" : [
"GW_NAME" : [ "10:10" , "198.41.1.1" ]

]
]
],
"TLV" : [
"TYPE" : [ "PrivateType65510" : 65510 ],
"Len" : 0,
"Data" : [
]
],

]
]
]
]
]
]
]]></artwork>
<postamble>
</postamble>
</figure>
<figure>
<preamble>Response encoded in JSON:
</preamble>
<artwork><![CDATA[
"PACKET (RFC 1035)" : [
"ROLE" : "client",
"DSIZE" : 38,
"DICTIONARY" : [
"example",
"com",
"",
"@0",
""
],
"DSIZE2" : 38,
"Header" : [
"ID" : 42,
"HFlags" : [
"QR" : true,
"Opcode" : [ "Query" : 0 ],
"AA" : false,
"TC" : false,
"RD" : true,
"RA" : true,
"Z" : false,
"AD" : true,
"CD" : false,
"RCODE" : [ "NoError (RFC 1035)" : 0 ]

],
"QDCOUNT" : 1,
"ANCOUNT" : 1,
"NSCOUNT" : 0,
"ARCOUNT" : 1
],
"Question" : [
"QUESTION (RFC 1035)" : [
"QNAME" : [ "example.com." : 0 ],
"QTYPE" : [ "A" : 1 ],
"QCLASS" : [ "IN" : 1 ]
]
],
"Answer" : [
"RR" : [
"NAME" : [ "example.com." : 0 ],
"TYPE" : [ "A" : 1 ],
"CLASS" : [ "IN" : 1 ],
"TTL" : 4084,
"RDLENGTH" : 4,
"RDATA" : [
"A" : [
"Address" : "93.184.216.119"
]
]
]
],
"Additional" : [
"RR" : [
"NAME" : [ "." : 4 ],
"TYPE" : [ "OPT" : 41 ],
"Field3" : [
"UDPSIZEFIELD" : [
"UDPSIZE" : 512
]
],
"Field4" : [
"Extended_RCode_Flags" : [
"ERCFlagbits" : [
"RCode" : 0,
"Version" : 0,
"DO" : false,
"Resv" : 0

]
]
],
"RDLENGTH" : 19,
"RDATA" : [
"OPT (RFC 6891)" : [
"TLV_LIST" : [
"TLV" : [
"TYPE" : [ "PrivateType65500" : 65500 ],
"Len" : 13,
"Data" : [
"PrivateType65500" : [
"GW_NAME" : [ "10:10" , "198.41.1.1" ]

]
]
],
"TLV" : [
"TYPE" : [ "PrivateType65510" : 65510 ],
"Len" : 0,
"Data" : [
]
],

]
]
]
]
]
]
]]></artwork>
<postamble>
</postamble>
</figure>
  </t>
  </section>
  <section title="Simple Query/Answer, with EDNS and DNS Server">
  <t>
<figure>
<preamble>Query encoded in JSON:
</preamble>
<artwork><![CDATA[
"PACKET (RFC 1035)" : [
"ROLE" : "client",
"DSIZE" : 31,
"DICTIONARY" : [
"example",
"com",
"",
""
],
"DSIZE2" : 31,
"Header" : [
"ID" : 42,
"HFlags" : [
"QR" : false,
"Opcode" : [ "Query" : 0 ],
"AA" : false,
"TC" : false,
"RD" : true,
"RA" : false,
"Z" : false,
"AD" : false,
"CD" : false,
"RCODE" : [ "NoError (RFC 1035)" : 0 ]

],
"QDCOUNT" : 1,
"ANCOUNT" : 0,
"NSCOUNT" : 0,
"ARCOUNT" : 1
],
"Question" : [
"QUESTION (RFC 1035)" : [
"QNAME" : [ "example.com." : 0 ],
"QTYPE" : [ "A" : 1 ],
"QCLASS" : [ "IN" : 1 ]
]
],
"Additional" : [
"RR" : [
"NAME" : [ "." : 3 ],
"TYPE" : [ "OPT" : 41 ],
"Field3" : [
"UDPSIZEFIELD" : [
"UDPSIZE" : 1500
]
],
"Field4" : [
"Extended_RCode_Flags" : [
"ERCFlagbits" : [
"RCode" : 0,
"Version" : 0,
"DO" : false,
"Resv" : 0

]
]
],
"RDLENGTH" : 15,
"RDATA" : [
"OPT (RFC 6891)" : [
"TLV_LIST" : [
"TLV" : [
"TYPE" : [ "PrivateType65500" : 65500 ],
"Len" : 13,
"Data" : [
"PrivateType65500" : [
"GW_NAME" : [ "10:10" , "198.41.1.1" ]

]
]
],

]
]
]
]
]
]
]]></artwork>
<postamble>
</postamble>
</figure>
<figure>
<preamble>Response encoded in JSON:
</preamble>
<artwork><![CDATA[
"PACKET (RFC 1035)" : [
"ROLE" : "client",
"DSIZE" : 38,
"DICTIONARY" : [
"example",
"com",
"",
"@0",
""
],
"DSIZE2" : 38,
"Header" : [
"ID" : 42,
"HFlags" : [
"QR" : true,
"Opcode" : [ "Query" : 0 ],
"AA" : false,
"TC" : false,
"RD" : true,
"RA" : true,
"Z" : false,
"AD" : true,
"CD" : false,
"RCODE" : [ "NoError (RFC 1035)" : 0 ]

],
"QDCOUNT" : 1,
"ANCOUNT" : 1,
"NSCOUNT" : 0,
"ARCOUNT" : 1
],
"Question" : [
"QUESTION (RFC 1035)" : [
"QNAME" : [ "example.com." : 0 ],
"QTYPE" : [ "A" : 1 ],
"QCLASS" : [ "IN" : 1 ]
]
],
"Answer" : [
"RR" : [
"NAME" : [ "example.com." : 0 ],
"TYPE" : [ "A" : 1 ],
"CLASS" : [ "IN" : 1 ],
"TTL" : 4084,
"RDLENGTH" : 4,
"RDATA" : [
"A" : [
"Address" : "93.184.216.119"
]
]
]
],
"Additional" : [
"RR" : [
"NAME" : [ "." : 4 ],
"TYPE" : [ "OPT" : 41 ],
"Field3" : [
"UDPSIZEFIELD" : [
"UDPSIZE" : 512
]
],
"Field4" : [
"Extended_RCode_Flags" : [
"ERCFlagbits" : [
"RCode" : 0,
"Version" : 0,
"DO" : false,
"Resv" : 0

]
]
],
"RDLENGTH" : 15,
"RDATA" : [
"OPT (RFC 6891)" : [
"TLV_LIST" : [
"TLV" : [
"TYPE" : [ "PrivateType65500" : 65500 ],
"Len" : 13,
"Data" : [
"PrivateType65500" : [
"GW_NAME" : [ "10:10" , "198.41.1.1" ]

]
]
],

]
]
]
]
]
]
]]></artwork>
<postamble>
</postamble>
</figure>
  </t>
  </section>
  </section>
  <section title="Server Gateway HTML code">
  <t>
<figure>
<preamble>The entire HTML document needed on the Server for the Client to send/receive JSON-encoded DNS messages follows:</preamble>
<artwork><![CDATA[
    <html>
    <body>
    <form action="cgi-bin/json-resolver2.pl" method="POST">
    <P>
    <TEXTAREA name="query" rows="20" cols="80">
    </TEXTAREA>
    <INPUT type="submit" value="Send"><INPUT type="reset">
    </P>
    </form>
    </body>
    </html>
]]></artwork>
<postamble>The "action" target needs to exist and be executable, and ideally be performance-optimized (e.g. via use of mod_perl).</postamble>
</figure>
  </t>
  </section>
  <section title="Server Gateway HTTP POST Handler Pseudo-code">
  <t>
  The following pseudo-code illustrates the high-level behavior of the HTML handler for the Server.
    <vspace blankLines="1" />
  The handler is passed the contents of the TEXTAREA, which will be the JSON-encoded DNS message.
<figure>
<artwork><![CDATA[
// initialize parser etc.
// set up socket for UDP query/response to default Resolver
// set up socket for UDP query/response to client-supplied Resolver
// extract JSON-encoded DNS message from HTTP POST variable 'query'
// save original Query-ID, assign new Query-ID (to avoid collisions)
// decode DNS message (into DNS wire format)
// if DNS message has OPT Resource Record
//   if OPT has Client-supplied Resolver option
//     extract Resolver value
//     delete Resolver option from OPT
//   endif
//   if OPT was synthesized by Client
//     delete OPT Resource Record
//   endif
//   send DNS message to Client-specified Resolver
// else
//   send DNS message to default Resolver
// endif
// wait for response or timeout
// if timeout && retry-count < max-retry-count
//   resend DNS message
// elsif timeout && retry-count >= max-retry-count
//   send "retry-count-exceeded" via OPT (synthesized if necessary)
// else
//   set DNS answer's Query-ID value to original Query-ID
//   encode DNS answer
//   send JSON-encoded answer to Client
// endif
]]></artwork>
</figure>
  </t>
  </section>
  <section title="Client Gateway Pseudo-code">
  <t>
  The following pseudo-code illustrates the high-level behavior of the Client.
    <vspace blankLines="1" />
  The Client in this example is pre-configured with a single Server Gateway's address.
<figure>
<artwork><![CDATA[
// initialize parser etc.
// set up socket for UDP query/response (Listener)
// set up HTTP connection to Server Gateway
// do an HTTP "GET" to the predefined URL of the Server HTML code
// extract HTML elements needed: handler, variable name
// loop forever:
//   listen for DNS query packet
//   fork (to handle this packet)
//   if child
//     save old DNS Query-ID, set new Query-ID
//     if Use-Supplied-Resolver
//       if exits OPT
//         add client-supplied-resolver to OPT
//       else
//         synthesize OPT and add client-supplied-resolver
//       endif
//     endif
//     encode DNS message (into JSON)
//     write HTTP POST onto socket
//     wait for HTTP response
//     extract JSON-encoded answer from HTTP
//     decode DNS answer (from JSON)
//     if OPT
//       if OPT.option is error condition
//         drop answer and continue loop forever:
//       elsif OPT synthesized
//         delete OPT
//       elsif OPT.option SPARTACUS-specific value
//         delete option
//       endif
//     endif
//     set answer.Query-ID to saved value
//     send answer to sender
//   end-of-loop
]]></artwork>
</figure>
  </t>
  </section>
  </back>
</rfc>
