On 05-Oct-2015 03:48 pm, Ted Hardie <[email protected]> wrote: 
> That said, the shim layer proposal seems at first glance to a pretty simple 
> extension of the multiplexing mechanics already described.  That is, you have 
> the QueryID to allow you to interleave requests; you use that in 
> demultiplexing responses.  If you have that and the DNS response in the first 
> DTLS record referencing a QueryID indicates truncation, you look for further 
> DTLS records referencing the same QueryID, and re-assemble them with the 
> first using a sequence number.
> 
> Yes, that would require more specification than in the document, but it seems 
> like a reasonable approach and it avoid re-starting the protocol machinery 
> (which fallback to TLS would do).
> 
> Am I missing a complication here?

I wrote up how to do this fragmentation/reassembly shim layer, and would like 
the WG's feedback.  I consulted several people on this idea, who discouraged us 
from doing a fragmentation/reassembly shim, so I am reluctant to share this 
write-up.  But the WG appears interested in analyzing the technical merits of a 
fragmentation/reassembly shim.

One complication, caused by UDP, is the DNS resource record can change between 
the initial query and the re-transmitted query, which means idempotency is lost 
(from the perspective of the client), corrupting the reassembled response.  To 
avoid this corruption, Tiru, Prashanth and I weighed a bunch of ideas and chose 
a 16-bit Master Fragment Sequence Number, which is described below.

Comments welcome.

-d

-----


10.  Fragmentation and Reassembly

   This section describes an optional procedure the client and server
   can negotiate to send large DNS responses without IP fragmentation or
   reassembly.

   Large DNS responses cannot exceed the DNS maximum payload size (512)
   unless a larger size is negotiated with EDNS0.  Even using EDNS0,
   requesting responses larger the path MTU causes IP fragmentation.  If
   the response exceeds that size it is truncated and the TC bit set,
   forcing a DNS client that wants the entire response to establish a
   TCP connection and send the query again over TCP.  This slows down
   DNS lookups, and is even more troublesome if a TLS session also needs
   to be established.

   To avoid these problems with DNS over DTLS, the DNS client and the
   DNS server can indicate support for a new application-layer
   fragmentation and reassembly mechanism, by using the new DTLS
   extension "DNS-fragment" in the DTLS ClientHello, and indicate how
   many fragments the client is willing to receive.  If the server
   supports this extension, it includes "DNS-fragment" in its DTLS
   ServerHello and indicates how many fragments it is willing to send in
   a response.  The EDNS0 value controls the size of the responses,
   including the size of fragmented responses.  If both the DTLS client
   and DTLS server indicate support DNS-fragment, and the DNS server's
   response exceeds the EDNS0-indicated size, the DNS server fragments
   the response into packets that are no larger than the EDNS0-indicated
   size, and sends them all to the DNS client.  Logically, the layering
   of the fragmentation is like this,

                              |     DNS       |
                              | fragmentation |
                              |     DTLS      |
                              |     UDP       |
                              |      IP       |

10.1.  Generating fragmented packets

   The response is formed, and separate packets are sent with their own
   fragmentation header, as follows:

                                             1  1  1  1  1  1
               0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
             |               DNS Query ID                    |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
             |QR| 1| M| M| Fragment-count  | Fragment-ID     |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
             |     Master Fragment Sequence Number (MFSN)    |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

   The above fragment header appears at the beginning of all fragments.
   The fields are defined as follows:

      DNS Query ID: Is the same as the ID value of the DNS response;
      this means the first fragment has the DNS Query ID value appear
      twice in the packet, and means subsequent fragments will contain
      their associated DNS Query ID in the fragmentation header.

      QR: This is the QR field in a normal DNS packet, and is always
      set, because fragmentation/reassembly is only defined in this
      document for responses.

      OP: This bit is always set.  This bit corresponds to first bit of
      the Opcode field of a normal DNS packet; that Opcode field for a
      normal DNS packet must be all 0.  By setting this bit to 1, this
      fragmentation header is distinguished from a normal DNS packet.

      M: The next two "M" bits must be 0, for future use.

      Fragment-count: For each query ID that generates a fragmented
      response, this field is set to the number of fragments that will
      be sent (that is, the highest Fragment-ID minus 1).

      Fragment-ID: Starts at 0 for the first fragmented segment and is
      incremented for each fragment.

      Master Fragment Sequence Number: starts at 0 and is incremented
      for the first packet of each fragmented response.

   The length of each fragment is calculated from the UDP packet size
   minus the DTLS overhead.

   It is RECOMMENDED that a value not exceeding 10 is used by the DNS
   client and DNS server during their DNS-fragment negotiation
   [RFC6928].  If the server needs to generate more fragments than were
   negotiated, MUST set the TC bit and SHOULD send the number of
   fragments negotiated.

   The fragments MUST be at least 64 bytes (minimum Ethernet MTU) minus
   DTLS, UDP, and IP overhead.  The fragments need not all be the same
   size.

   todo: decide how EDNS works with the 48-byte fragment header

10.2.  Receiving fragmented packets

   Upon receipt of a DTLS packet, DTLS processing is performed and the
   Opcode field is examined to determine if reassembly is required
   before processing as a DNS packet, as depicted below:

               +--------+
               | 00000 -+------------> DNS processing
      Opcode = |        |                  ^
               |        |                  |
               | 1xxxx -+--->reassembly----+
               +--------+

   If reassembly needs to be performed, the packets are matched
   according to their DNS query ID value (at the top of the fragment
   header), their Master Fragment Sequence Number, and ordered by their
   Fragment-ID.  Once all the fragments have been received (that is, all
   fragments from 0 through the Fragment-ID matching the frag-count
   minus 1), the fragment headers are removed and the DNS payload is
   handed to the DNS layer.  Due to network loss or packet corruption,
   some fragments might not be received, which will cause the DNS layer
   to perform a normal re-transmission of the DNS query, with the same
   query ID.  The re-transmitted answer, which will be fragmented
   identically to the original answer (assuming that resource record did
   not change between the two answers), will have a different Master
   Fragment Sequence Number.

      Design Note: Tha MFSN protects against corruption caused by DNS
      resource record changing between the initial query and its re-
      transmitted query.

   After a time out, incomplete fragments are discarded by the receiver.

   If the Fragment-ID is 0 and the DNS Query ID value in the fragment
   header does not match the ID value in the DNS header, a DTLS Alert is
   generated and an error is logged.

_______________________________________________
dns-privacy mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/dns-privacy

Reply via email to