Subject: A mechanism to encode HTTP version information in DNS

From: Phillip Hallam-Baker <[email-masked]>
Date: Thu, 14 Feb 2013 15:16:28 -0500

Encoding HTTP version information in DNS is easy if you don't particularly
care about using DNS properly or want to do anything more than encode HTTP
version information.

Doing it well gets rather more complex. A DNS query costs a round trip so
you would ideally like to make it pay. Also the process of deploying DNS
records takes some time and it is better to reuse an existing record but
only if that will not create ambiguity.

Looking again at the URI record, I think that we could use it to provide a
HTTP version flag and other useful features in the DNS. In particular we
can use the URI record to effect a HTTP redirect in DNS (a UDP round trip)
rather than require a TCP round trip. It also provides for fault tolerance
and load balancing and works well with Web Services.

The format of the URI record is currently: <priority> <weight> <Target>

Priority - uint16
Weight - uint16
Target - string

While Target is technically a list of string entries it is not a good idea
to depend on the string boundaries for technical reasons and so multiple
strings should probably be considered equivalent to the result of
concatenating them together.

For example: two servers offering HTTP service for 'example.com'
_http._tcp.example.com  URI 10 10 "http://www1.example.com/"
_http._tcp.example.com  URI 10 10 "http://www2.example.com/"

OK so that is not very interesting but the existing but the URI scheme also
permits services to be advertised under a different scheme such as https or
coap (or ftp if you must!)

So to force an upgrade to TLS we might specify the following:

_http._tcp.example.com  URI 10 10 "https://www1.example.com/"
_http._tcp.example.com  URI 10 10 "https://www2.example.com/"

Or to advertise multiple protocols:

_http._tcp.example.com  URI 10 10 "http://www1.example.com/"
_http._tcp.example.com  URI 10 10 "coap://www1.example.com/"

Or to map a domain to a path on another server:

_http._tcp.old.example.com  URI 10 10 "https://www1.example.com/old-stuff"

All those capabilities are useful in the context of HTTP discovery. They
allow a redirect to be effected through the DNS rather than require a
server deployment. But it would be much nicer if we could encode both a
target URI and some description of that target to allow client selection.
For example:

* IP version
* HTTP protocol version
* HSTS data

We don't always need this data but when we do it is very useful. But it
turns out that the existing URI record might already meet this need since a
URI cannot have a space inside it and so we can use that as a delimeter
between the target URI and any parameters. We are currently discussing the
details of this on DNSEXT but it looks like it works fine.

_http._tcp.example.com  URI 10 10 "http://www1.example.com/ ipv4 ipv6"
_http._tcp.example.com  URI 10 10 "http://www2.example.com/ http2"
_http._tcp.example.com  URI 10 10 "http://www3.example.com/ sts"

The same mechanism can be used to effect pinning or to alert the client to
the existence of a DANE record.

Knowing whether the site supports IPv4 or IPv6 or both allows us to
optimize any A record lookup.

We could even specify the ASN number of the server IP address in the URI
record. Why might you want to know that? Well it allows a client to select
a server likely to be closer

The same mechanism can be used for a Web Service only there we would use
the protocol prefix of the Web Service rather than HTTP.

-- 
Website: http://hallambaker.com/

---

From: Amos Jeffries <[email-masked]>
Date: Fri, 15 Feb 2013 18:46:52 +1300

On 15/02/2013 9:16 a.m., Phillip Hallam-Baker wrote:
> Encoding HTTP version information in DNS is easy if you don't 
> particularly care about using DNS properly or want to do anything more 
> than encode HTTP version information.
>
> Doing it well gets rather more complex. A DNS query costs a round trip 
> so you would ideally like to make it pay. Also the process of 
> deploying DNS records takes some time and it is better to reuse an 
> existing record but only if that will not create ambiguity.
>
> Looking again at the URI record, I think that we could use it to 
> provide a HTTP version flag and other useful features in the DNS. In 
> particular we can use the URI record to effect a HTTP redirect in DNS 
> (a UDP round trip) rather than require a TCP round trip. It also 
> provides for fault tolerance and load balancing and works well with 
> Web Services.

One small note on this assertion:
   FQDN are capable of being anything up to 256 octets long *per-label*. 
When the FQDN is greater than 250 octets or so this will add both a UDP 
round trip plus a TCP round trip, on top of the final connection setup 
round trip. This may not seem a critical point, but we are already 
encountering web sites and services with >64 octet FQDN in public 
traffic which is causing TLS certificate issues.

That asside, I am liking this proposal better than any of the earlier 
DNS proposals. I can forsee support from Squid being implemented if this 
is selected to go ahead.

Amos

---

From: "Adrien W. de Croy" <[email-masked]>
Date: Fri, 15 Feb 2013 08:05:53 +0000

Are you talking about DNS labels?

DNS label max length is 63 (6 bits) only, due to overloading of offset 
pointer with label length.

overall domain name max length is 255, although this is I guess 
relatively arbitrary, it's possible to code a longer name on a DNS 
packet, but not a longer label.

------ Original Message ------
From: "Amos Jeffries" <[email-masked]>
To: "[email-masked]" <[email-masked]>
Sent: 15/02/2013 6:46:52 p.m.
Subject: Re: A mechanism to encode HTTP version information in DNS
>DNS proposals. I can forsee support from Squid being implemented if 
>this is selected to go ahead.
>
>Amos
>
>

---

From: Amos Jeffries <[email-masked]>
Date: Sat, 16 Feb 2013 15:19:46 +1300

> Are you talking about DNS labels?
I was yes. Does this include the URL string label?

> packet, but not a longer label.

So the big question: is the URL string field a label? or do we catenate 
it from multiple labels?

Amos

>>> particularly care about using DNS properly or want to do anything 
>>> more than encode HTTP version information.
>>>
>>> Doing it well gets rather more complex. A DNS query costs a round 
>>> trip so you would ideally like to make it pay. Also the process of 
>>> particular we can use the URI record to effect a HTTP redirect in 
>>> DNS (a UDP round trip) rather than require a TCP round trip. It also 
>>   FQDN are capable of being anything up to 256 octets long 
>> *per-label*. When the FQDN is greater than 250 octets or so this will 
>> add both a UDP round trip plus a TCP round trip, on top of the final 
>> connection setup round trip. This may not seem a critical point, but 
>> we are already encountering web sites and services with >64 octet 
>> FQDN in public traffic which is causing TLS certificate issues.
>>
>>

---

From: "Adrien W. de Croy" <[email-masked]>
Date: Sat, 16 Feb 2013 06:34:17 +0000

------ Original Message ------
From: "Amos Jeffries" <[email-masked]>
To: "Adrien W. de Croy" <[email-masked]>
Cc: "[email-masked]" <[email-masked]>
Sent: 16/02/2013 3:19:46 p.m.
Subject: Re: A mechanism to encode HTTP version information in DNS
>I was yes. Does this include the URL string label?

if you mean the URI RR data field (as per draft-faltstrom-uri), it can 
be quite long, being defined as a sequence of one or more 
<character-string> which are (byte) length-prefixed strings, but which 
can be concatenated.

It would more likely run into limitations on max datagram size.  I think 
implementations are supposed to handle at least 576 bytes, but to go 
bigger is a DNS extension, and I don't know how well supported it is. 
Otherwise you fail over to DNS over TCP, which I think would be 
problematic in our case due to added RTs / latency.

in DNS, a label refers to a part of a name (e.g. FQDN is a sequence of 
labels separated by dots), so "URL string label" is a bit confusing.

If you're referring to the authority part of a URI, being a domain name, 
it is subject to the limitations of DNS.

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Sat, 16 Feb 2013 11:13:55 -0500

On Sat, Feb 16, 2013 at 1:34 AM, Adrien W. de Croy <[email-masked]> wrote:

> if you mean the URI RR data field (as per draft-faltstrom-uri), it can be
> quite long, being defined as a sequence of one or more <character-string>
> which are (byte) length-prefixed strings, but which can be concatenated.
>
> implementations are supposed to handle at least 576 bytes, but to go bigger
> is a DNS extension, and I don't know how well supported it is. Otherwise
> you fail over to DNS over TCP, which I think would be problematic in our
> case due to added RTs / latency.
>

The URI RR scheme allows for multiple string entries but does not fully
specify the semantics (it is a draft after all).

Given existing DNS infrastructure and its treatment of TXT records, the
interpretation least likely to cause issues is to simply catenate the
separate string entries.

While you could int theory have a really long URI here, it would be stupid
and unnecessary to do that. In the first place this is the Web Service
Endpoint which is frequently the prefix rather than the actual URI. If some
idiot has a 512 byte URI for the Web Service endpoint they are not going to
have room for Web Service parameters.

Since DNS does work over TCP, the reasonable answer to stupid
configurations like that is 'they are going to be less efficient and break
if infrastructure is not standards compliant'.

---

From: Eliot Lear <[email-masked]>
Date: Sun, 17 Feb 2013 11:59:24 +0100

Phillip,

You're hitting at the heart of a key issue, and rather than focus on
mechanisms, I urge folk to take a look at the very beginning of
draft-lear-httpbis-svcinfo-rr where I state design goals.  One of those
goals is to not harm latency.  What you describe below introduces a
dependency of  QNAME on target, forcing an additional query, which is
one of the key issues with SRV.

Now, I am not saying that's the wrong thing to do.  But I am saying that
it violates that stated design goal.  Maybe the goal is the wrong one to
have?

Eliot

On 2/14/13 9:16 PM, Phillip Hallam-Baker wrote:
> While Target is technically a list of string entries it is not a good
> idea to depend on the string boundaries for technical reasons and so
> multiple strings should probably be considered equivalent to the
> result of concatenating them together.
>
> For example: two servers offering HTTP service for 'example.com
> <http://example.com>'
> _http._tcp.example.com <http://tcp.example.com>  URI 10 10
> "http://www1.example.com/"
> _http._tcp.example.com <http://tcp.example.com>  URI 10 10
> "http://www2.example.com/"
>
> OK so that is not very interesting but the existing but the URI scheme
> also permits services to be advertised under a different scheme such
> as https or coap (or ftp if you must!)
>
> _http._tcp.example.com <http://tcp.example.com>  URI 10 10
> "https://www1.example.com/"
> _http._tcp.example.com <http://tcp.example.com>  URI 10 10
> "https://www2.example.com/"
>
> _http._tcp.example.com <http://tcp.example.com>  URI 10 10
> "http://www1.example.com/"
> _http._tcp.example.com <http://tcp.example.com>  URI 10 10
> "coap://www1.example.com/ <http://www1.example.com/>"
>
> _http._tcp.old.example.com <http://tcp.old.example.com>  URI 10 10
> "https://www1.example.com/old-stuff"
>
>
> All those capabilities are useful in the context of HTTP discovery.
> They allow a redirect to be effected through the DNS rather than
> require a server deployment. But it would be much nicer if we could
> encode both a target URI and some description of that target to allow
> client selection. For example:
>
> * IP version
> * HTTP protocol version
> * HSTS data
>
> We don't always need this data but when we do it is very useful. But
> it turns out that the existing URI record might already meet this need
> since a URI cannot have a space inside it and so we can use that as a
> delimeter between the target URI and any parameters. We are currently
> discussing the details of this on DNSEXT but it looks like it works fine.
>
> _http._tcp.example.com <http://tcp.example.com>  URI 10 10
> "http://www1.example.com/ ipv4 ipv6"
> _http._tcp.example.com <http://tcp.example.com>  URI 10 10
> "http://www2.example.com/ http2"
> _http._tcp.example.com <http://tcp.example.com>  URI 10 10
> "http://www3.example.com/ sts"
>
> The same mechanism can be used to effect pinning or to alert the
> client to the existence of a DANE record.
>
> We could even specify the ASN number of the server IP address in the
> URI record. Why might you want to know that? Well it allows a client
> to select a server likely to be closer
>
>
> The same mechanism can be used for a Web Service only there we would
> use the protocol prefix of the Web Service rather than HTTP. 
>
> --

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Sun, 17 Feb 2013 08:10:26 -0500

On Sun, Feb 17, 2013 at 5:59 AM, Eliot Lear <[email-masked]> wrote:

> dependency of  QNAME on target, forcing an additional query, which is one
> of the key issues with SRV.
>

example.com 1 2 http://10.1.2.3/dns/folk/dont/like/litteral/addresses/

(shhh)

---

From: Patrick McManus <[email-masked]>
Date: Sun, 17 Feb 2013 11:14:56 -0500

That's the right goal :)

On Sun, Feb 17, 2013 at 5:59 AM, Eliot Lear <[email-masked]> wrote:
> dependency of  QNAME on target, forcing an additional query, which is one of
> the key issues with SRV.
>
> Now, I am not saying that's the wrong thing to do.  But I am saying that it
> violates that stated design goal.  Maybe the goal is the wrong one to have?
>
> Eliot
>
> HTTP version flag and other useful features in the DNS. In particular we can
> use the URI record to effect a HTTP redirect in DNS (a UDP round trip)
> allow a redirect to be effected through the DNS rather than require a server
> deployment. But it would be much nicer if we could encode both a target URI
> and some description of that target to allow client selection. For example:
>
> * IP version
> * HTTP protocol version
> * HSTS data
>
> Knowing whether the site supports IPv4 or IPv6 or both allows us to optimize
> any A record lookup.
>
> record. Why might you want to know that? Well it allows a client to select a
> server likely to be closer
>
>
> The same mechanism can be used for a Web Service only there we would use the
> protocol prefix of the Web Service rather than HTTP.
>
> --

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Sun, 17 Feb 2013 13:18:53 -0500

The answer I think the DNS folk will give is that A and AAAA should be the
only records that translate DNS names to IP addresses and that if a server
gets a request for a record like SRV then it should deliver any A/AAAA
records referenced as additional records.

I am not saying I agree with that analysis but it is the one I think they
will give...

The administrative issue I think they would worry about is the case where
there are multiple services on the same host and the desire is to change
the IP address of the host as an atomic action.

Again, I am not sure that is a necessary consideration. What might be more
of a consideration is wanting to ensure IPv4/v6 compatibility.

Is there any reason not to use the built in DNS additional records
mechanism? It only works when the server for the URI / SRV record is also
the server for the A record. BUT this is what you would want. in the rare
case that you would have the A record on a different DNS server it would be
because you wanted another admin to manage the mapping. That is the
argument for MX records at any rate (I think).

On Sun, Feb 17, 2013 at 11:14 AM, Patrick McManus <[email-masked]>wrote:

> it
> particularly
> can
> idea
> also
> server
> the

---

From: "Adrien W. de Croy" <[email-masked]>
Date: Sun, 17 Feb 2013 21:31:49 +0000

I've always thought one of the issues with SRV is the transport is in 
the wrong part - the name, so you can't specify that with the result.

For something new, we should look at putting the transport into the RR 
data instead of the name

then it makes it possible to deploy over multiple transports later on, 
e.g. SCTP, UDP whatever if desired.

------ Original Message ------
From: "Eliot Lear" <[email-masked]>
To: "Phillip Hallam-Baker" <[email-masked]>
Cc: "[email-masked] Group" <[email-masked]>
Sent: 17/02/2013 11:59:24 p.m.
Subject: Re: A mechanism to encode HTTP version information in DNS
>Now, I am not saying that's the wrong thing to do.  But I am saying 
>that it violates that stated design goal.  Maybe the goal is the wrong 
>one to have?
>
>Eliot
>

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Sun, 17 Feb 2013 17:05:44 -0500

On Sun, Feb 17, 2013 at 4:31 PM, Adrien W. de Croy <[email-masked]> wrote:

>
> I've always thought one of the issues with SRV is the transport is in the
> wrong part - the name, so you can't specify that with the result.
>

That is exactly what the URI RR does, the target is a URI which can of
course specify a new scheme.

I think it best to treat _http._tcp as simply a code point corresponding to
the http URI scheme and the _tcp part as just a default..

If you wanted to specify a different transport then you would either
specify a different scheme or you would specify it as a discovery parameter
for that scheme.

> also permits services to be advertised under a different scheme such as
> https or coap (or ftp if you must!)
>

---

From: "Adrien W. de Croy" <[email-masked]>
Date: Sun, 17 Feb 2013 22:31:23 +0000

basically anything in the name is not discoverable.

So if the name contains _tcp, we're not doing discovery on transport.  
We're presuming there is a _tcp deployment etc.

We should take a step back and ask what are we trying to discover.  It 
makes not much sense to me to leave transport out of that.

------ Original Message ------
From: "Phillip Hallam-Baker" <[email-masked]>
To: "Adrien W. de Croy" <[email-masked]>
Cc: "Eliot Lear" <[email-masked]>; "[email-masked] Group" 
<[email-masked]>
Sent: 18/02/2013 11:05:44 a.m.
Subject: Re: A mechanism to encode HTTP version information in DNS
>I think it best to treat _http._tcp as simply a code point 
>corresponding to the http URI scheme and the _tcp part as just a 
>default..
>
>specify a different scheme or you would specify it as a discovery 
>parameter for that scheme.
>
>
>
>>>draft-lear-httpbis-svcinfo-rr where I state design goals.  One of 
>>>those goals is to not harm latency.  What you describe below 
>>>introduces a dependency of  QNAME on target, forcing an additional 
>>>query, which is one of the key issues with SRV.
>>>
>>>that it violates that stated design goal.  Maybe the goal is the 
>>>wrong one to have?
>>>
>>>Eliot
>>>
>>>>While Target is technically a list of string entries it is not a 
>>>>good idea to depend on the string boundaries for technical reasons 
>>>>and so multiple strings should probably be considered equivalent to 
>>>>the result of concatenating them together.
>>>>
>>>>OK so that is not very interesting but the existing but the URI 
>>>>scheme also permits services to be advertised under a different 
>>>>scheme such as https or coap (or ftp if you must!)
>>>>
>>>>encode both a target URI and some description of that target to 
>>>>allow client selection. For example:
>>>>
>>>>* IP version
>>>>* HTTP protocol version
>>>>* HSTS data
>>>>
>>>>it turns out that the existing URI record might already meet this 
>>>>need since a URI cannot have a space inside it and so we can use 
>>>>that as a delimeter between the target URI and any parameters. We 
>>>>are currently discussing the details of this on DNSEXT but it looks 
>>>>like it works fine.
>>>>

---

From: Amos Jeffries <[email-masked]>
Date: Mon, 18 Feb 2013 11:41:43 +1300

On 18/02/2013 11:05 a.m., Phillip Hallam-Baker wrote:
>
>
> On Sun, Feb 17, 2013 at 4:31 PM, Adrien W. de Croy <[email-masked] 
> <mailto:[email-masked]>> wrote:
>
>     I've always thought one of the issues with SRV is the transport is
>     in the wrong part - the name, so you can't specify that with the
>     result.
>     For something new, we should look at putting the transport into
>     the RR data instead of the name
>     then it makes it possible to deploy over multiple transports later
>     on, e.g. SCTP, UDP whatever if desired.
>
>
> corresponding to the http URI scheme and the _tcp part as just a default..
>

Or since HTTP is effectively a transport in these respects we have _http 
defined alongside _tcp, and make the under-layer transport an option in 
URI RR

   _http.example.com <http://tcp.example.com>  URI 10 10 
"http://www1.example.com/ TCP HTTP/2.0"

With default option for under-layer being TCP when no other is mentioned 
specifically.

Amos