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