Subject: Re: [dnsext] FQDN maximum length

From: Stuart Cheshire <[email-masked]>
Date: Fri, 01 Jan 2010 09:39:56 -0800

On 31 Dec 2009, at 8:14, Donald Eastlake wrote:

> Possibly the 255 byte wire encoding limit was chosen so the byte  
> string could be represented inside a computer for processing in 256  
> bytes by adding a length byte as Pascal might do.

Or possibly the 255 byte limit was chosen to leave one byte space for  
the zero terminator on the end?

In any case we made a decision for Multicast DNS that a domain name  
object in memory can be up to 256 bytes -- a convenient power of two  
-- which is 255 bytes for label octets and label length octets, plus  
one byte for the zero terminator on the end. And we wrote a document  
that said so very clearly, to avoid any confusion.

Stuart Cheshire <[email-masked]>
* Wizard Without Portfolio, Apple Inc.
* Internet Architecture Board
* www.stuartcheshire.org

---

From: Donald Eastlake <[email-masked]>
Date: Fri, 1 Jan 2010 18:21:21 -0500

Hi Stuart,

On Fri, Jan 1, 2010 at 12:39 PM, Stuart Cheshire <[email-masked]> wrote:

>  Possibly the 255 byte wire encoding limit was chosen so the byte string
>> could be represented inside a computer for processing in 256 bytes by adding
>> a length byte as Pascal might do.
>>
>
> Or possibly the 255 byte limit was chosen to leave one byte space for the
> zero terminator on the end?
>

Sure, lots of things could have been in the mind of the RFC author.

> In any case we made a decision for Multicast DNS that a domain name object
> in memory can be up to 256 bytes -- a convenient power of two -- which is
> 255 bytes for label octets and label length octets, plus one byte for the
> zero terminator on the end. And we wrote a document that said so very
> clearly, to avoid any confusion.
>

Well, since its Informational, you can set that number at whatever you want.

I don't particularly see the point of the stuff in the draft about how
ambiguous some parts of some DNS RFCs are. In the IETF, when the
specification of a protocol is ambiguous on a point and there are
interoperable implementations, the ambiguity is resolved by seeing what
those implementations do. Although it was before my time, I believe this was
established when early IPv4 interop testing was done. People were
interoperating fine with checksum checking turned off but when it was turned
on, most failed to interoperate due to differing interpretations of the
spec. The spec was then changed to what the largest number of interoperating
implementations were doing.

But the multicast DNS draft also speaks about compatibility with existing
unicast DNS implementations and how you can frequently just tweak the
address used. Seems like that won't be true for the corner case of domain
names whose wire encoding is 256 bytes. So, it seems to me that that should
be noted in the draft.

> * Internet Architecture Board

Thanks,
Donald
=============================
Donald E. Eastlake 3rd   +1-508-634-2066 (home)
155 Beaver Street
Milford, MA 01757 USA
[email-masked]

---

From: Donald Eastlake <[email-masked]>
Date: Thu, 31 Dec 2009 11:14:38 -0500

Hi Stuart,

While I respond in detail below, I think your basic problem is that you
didn't go about trying to clarify this ambiguity in the IETF way. You don't
resolve such things in the IETF by puzzling endlessly over every piece of
ambiguous RFC text you can find, as though it were some sort of holy writ.
Interoperability trumps the results of such puzzling and musing. "We believe
in rough consensus and *running cod**e*."

You should have asked any of the many well known DNS implementers or looked
at DNS open source or posted to the namedroppers mailing list with your
question. In any case, the conclusion you came to was incorrect.

On Wed, Dec 30, 2009 at 8:02 PM, Stuart Cheshire <[email-masked]> wrote:

> On 13 Dec 2009, at 18:48, Donald Eastlake wrote:
>
>  OK, here is what I think is a stupid question to which I think I know the
>> answer... but I wish to consult the wisdom of namedroppers.
>>
>
(The reason I said this was a stupid question was I was already quite sure
what the wire format limits were and just wanted to confirm this before
telling you.)

> I am doing a review of draft-cheshire-dnsext-multicastdns-08.txt. For some
>> reason, the authors believe that the words of RFC 1034 as follows
>>
>>     the total number of octets that represent a domain name (i.e.,
>>     the sum of all label octets and label lengths) is limited to 255
>>
>> are not clear. I thought they were clear.
>
>  As is often the case, things that may superficially appear clear at a
> casual glance are not so clear when you think about them more carefully.
>

The text quoted above seems perfectly clear to me no matter how much I think
about it. There is other more ambiguous text. But "the sum of all label
octets and label lengths" is absolutely clear. And, because it is talking
about lengths rather than periods/delimiters, it can't be talking about
anything but the wire encoding.

In any case, what the interoperable implementations do rules, not anyone's
thoughts, careful or not.

> RFC 1035 ("DNS Implementation and Specification") says:
>
>  2.3.4. Size limits
>>
>> Various objects and parameters in the DNS have size limits.  They are
>> listed below.  Some could be easily changed, others are more fundamental.
>>
>> labels          63 octets or less
>> names           255 octets or less
>
>  It would be nice if this said either:
>
>  labels          63 octets or less (including initial length byte)
>> names           255 octets or less (including final terminating zero)
>>
> or
>
>  labels          63 octets or less (excluding initial length byte)
>> names           255 octets or less (excluding final terminating zero)
>>
> Other context leads us to conclude that the label length limit does NOT
> include the initial length byte. Consistency would suggest that an
> equivalent interpretation might apply to the definition of name length
> limit.
>

You're right on labels, since the length is a 6 bit quantity with values
zero through 63 and if the length byte were included then the length value
field could not exceed 62 and there would need to be some text about what to
do if it has the value 63 and there is no such text.

But "consistency" and "equivalent interpretation" are in the eye of the
beholder. "Name" here seems to be short for fully qualified domain name
which includes the wire encoding of the terminating root label.

> Faced with this ambiguity, we consulted "Clarifications to the DNS
> Specification", RFC 2181.
>
> Given that the entire point of RFC 2181 was to recognize and remedy
> ambiguities in the original DNS specifications, one might hope that it was
> given thorough scrutiny by the IETF and DNSEXT to ensure that it did so, and
> consequently any information in it replaces and supersedes any unclear or
> ambiguous information in the earlier RFCs. RFC 2181 says:
>

But the problem is, as usual, that there are some things so fundamental that
all the knowledgeable people working on and reviewing such a document just
assume you know and think it's already clear since they just know what the
right thing is. It's commonly such simple, fundamental things that trip
people up. After all, if something is complex/rare/obscure, people will go
to pains explaining it thoroughly. But something as simple, common, and
plain as the wire encoding of domain names, which appear in every DNS
request and response and has been interoperably implemented many times over
many years, is easily glossed over.

>    The DNS itself places only one restriction on the particular labels
>>   that can be used to identify resource records.  That one restriction
>>   relates to the length of the label and the full name.  The length of
>>   any one label is limited to between 1 and 63 octets.  A full domain
>>   name is limited to 255 octets (including the separators).  The zero
>>
>>   length full name is defined as representing the root of the DNS tree,
>>   and is typically written and displayed as ".".
>>
> So, what do we make of that? Is this talking about the wire format of a
> domain name, or the conventional textual representation? The "including the
> separators" text implies this is talking about the textual representation,
> but it fails to say whether the trailing dot is included, and it also fails
> to say whether the trailing null byte typically at the end of a C string is
> included. As "clarifications" go, I've seen better. What's the length of "
> ietf.org"? Let's consider the four possibilities:
>
> (A) "ietf.org"    length =  8
> (B) "ietf.org."   length =  9
> (C) "ietf.org\0"  length =  9
> (D) "ietf.org.\0" length = 10
>

The wire encoding of this as an FQDN is always 10 bytes. The text encoding
is 9 as an FQDN and 8 as a relative domain name.

If you have this many possibilities and you find things this ambiguous about
something that has been interoperably implemented for so many years, why not
just ask?

It is true that one of the 103x DNS RFCs should had more hex examples,
including a specific example of a wire encoded maximum length domain name.

> Let's consider that for the case of the root name:
>
> (A) ""            length =  0
> (B) "."           length =  1
> (C) "\0"          length =  1
> (D) ".\0"         length =  2
>
> Is the length of "ietf.org" 8, 9 or 10? Is the length of the root name 0,
> 1, or 2? If only the document gave us some hint. Oh, wait, it does:
>
>    The zero length full name is defined as representing the root
>>   of the DNS tree, and is typically written and displayed as ".".
>>
> So RFC 2181 does tell us the answer. The length of "." is considered to be
> zero. So neither the trailing dot nor the trailing C-string null byte are
> included. That means interpretation (A) is the correct one, and the nominal
> "length" of "ietf.org" is 8.
>

I'm not claiming RFC 2181 is clear in this regard. The 2181 text is
confusing between text and wire representation.

The trailing null byte that ends all FQDNs has nothing to do with C-string
termination. It is the length of the label of the root node. There can be
embedded null bytes earlier in the FQDN inside other labels.

> This is consistent with other similar things in computing. A pascal string
> can be 0-255 bytes long, but it takes 1-256 bytes of storage, because of the
> length byte. Many software objects are a multiple of a power of two in size,
> because computers are more efficient at handling memory objects that are
> bus-aligned (typically 4 bytes), or cache-line aligned (e.g. 128-bytes), or
> VM-page aligned (e.g. 4KB).
>
> Limiting a domain name to 255 bytes of storage instead of 256 is just
> wasting a byte. In a C structure in memory, a 255-byte object is usually
> followed by an unused padding byte so that the next object is word-aligned.
>

But wire encoded fully qualified domain names are not C strings because a
zero byte is entirely valid inside a label. Possibly the 255 byte wire
encoding limit was chosen so the byte string could be represented inside a
computer for processing in 256 bytes by adding a length byte as Pascal might
do. But there is no overall FQDN length byte in the wire encoding.
Termination is indicated when you run into a zero value label length byte
since the zero length label is the label of root.

In such a world, where a pascal string can be 0-255 bytes long, and takes up
> to 256 bytes of storage, because of the length byte, it is consistent that:
>
> (a) a domain label can be up to 63 bytes long (and takes up to 64 bytes of
> storage, because of the length byte) and
> (b) a domain name can be up to 255 bytes long (and takes up to 256 bytes of
> storage, because of the terminating zero).

That's nice and, from some point of view, consistent, but it does not agree
with DNS implementations.

Thanks,
Donald