When a recursive resolver discovers the need for an authoritative lookup to an authoritative DNS server using IP address
X, it retrieves the records associated with
X from its cache.¶
The following sections presume that the time of the discovery of the need for lookup is time
The recursive resolver must know to decide whether to initially send a query over Do53, or over any of the supported encrypted transports (DoT or DoQ).¶
Note that a resolver might initiate this query via any or all of the known transports.
When multiple queries are sent, the initial packets for each connection can be sent concurrently, similar to "Happy Eyeballs" ([RFC8305]).
However, unlike Happy Eyeballs, when one transport succeeds, the other connections do not need to be terminated, but can instead be continued to establish whether the IP address
X is capable of corresponding on the relevant transport.¶
For any of the supported encrypted transports
E, if either of the following holds true, the resolver SHOULD NOT send a query to
X over Do53:¶
E-session[X] is in the
established state, or¶
(T - E-completed[X]) < persistence¶
Otherwise, if there is no outstanding session for any encrypted transport, and the last successful encrypted transport connection was long ago, the resolver sends a query to
X over Do53.
When it does so, it inserts a handle for the query in
E-session[X] is in the
established, the recursive resolver SHOULD NOT initiate a new connection to
X over any other transport, but should instead send a query through the existing session (see Section 4.5.8).
FIXME: What if there's a preferred transport, but the
established session does not correspond to that preferred transport?¶
Otherwise, the timer should examine and possibly refresh its state for encrypted transport
E to authoritative IP address
When resources are available to attempt a new encrypted transport, the resolver should only initiate a new connection to
E as long as one of the following holds true:¶
(T - E-completed[X]) > damping, or¶
When initiating a session to
X over encrypted transport
E-resumptions[X] is not empty, one ticket should be popped off the stack and used to try to resume a previous session.
Otherwise, the initial Client Hello handshake should not try to resume any session.¶
When initiating a connection, the resolver should take the following steps:¶
- store a handle for the new session (which should have
pending state) in
- insert a handle for the query that prompted this connection in
E-queries[X], with status
early, as appropriate (see below).¶
Modern encrypted transports like TLS 1.3 offer the chance to store "early data" from the client into the initial Client Hello in some contexts.
A resolver that initiates a connection over a encrypted transport according to this guidance in a context where early data is possible SHOULD send the DNS query that prompted the connection in the early data, according to the sending guidance in Section 4.5.8.¶
If it does so, the status of
E-queries[X] should be set to
early instead of
When initiating a new connection (whether by resuming an old session or not), the recursive resolver SHOULD request a session resumption ticket from the authoritative server.
If the authoritative server supplies a resumption ticket, the recursive resolver pushes it into the stack at
For modern encrypted transports like TLS 1.3, most client implementations expect to send a Server Name Indication (SNI) in the Client Hello.¶
There are two complications with selecting or sending SNI in this unilateral probing:¶
- Some authoritative servers are known by more than one name; selecting a single name to use for a given connection may be difficult or impossible.¶
- In most configurations, the contents of the SNI field is exposed on the wire to a passive adversary.
This potentially reveals additional information about which query is being made, based on the NS of the query itself.¶
To avoid additional leakage and complexity, a recursive resolver following this guidance SHOULD NOT send SNI to the authoritative when attempting encrypted transport.¶
If the recursive resolver needs to send SNI to the authoritative for some reason not found in this document, it is RECOMMENDED that it implements Encrypted Client Hello ([I-D.ietf-tls-esni] to reduce leakage.¶
Once established, an encrypted transport might fail for a number of reasons (e.g., decryption failure, or improper protocol sequence).¶
If this happens:¶
Note that this failure will trigger the recursive resolver to fall back to cleartext queries to the authoritative server at IP address
It will retry encrypted transport to
X once the
damping timer has elapsed.¶
FIXME: are there specific forms of failure that we might handle differently?
For example, What if a TCP timeout closes an idle DoT connection?
What if a QUIC stream ends up timing out but other streams on the same QUIC connection are going through?
Do the described scenarios cover the case when an encrypted transport's port is made unavailable/closed?¶
When sending a query to an authoritative server over encrypted transport at time
T4, the recursive resolver should take a few reasonable steps to ensure privacy and efficiency.¶
When sending query
Q, the recursive resolver should ensure that its state in
E-queries[X] is set to
The recursive resolver also sets
In addition, the recursive resolver should consider the following guidance:¶
To protect the privacy of the client, the recursive resolver SHOULD NOT send EDNS(0) Client Subnet information to the authoritative server ([RFC7871]) unless explicitly authorized to do so by the client.¶
To increase the anonymity set for each query, the recursive resolver SHOULD use EDNS(0) padding according to policies described in [RFC8467].¶
When multiple queries are multiplexed on a single encrypted transport to a single authoritative server, the recursive resolver MUST offer distinct query ID fields for every outstanding query on a connection, and MUST be capable of receiving responses out of order.¶
To the extent that the encrypted transport can avoid head-of-line blocking (e.g. QUIC can use a separate stream per query) the recursive resolver SHOULD avoid head-of-line blocking.¶
Over time, a recursive resolver following this policy may find that it is limited in resources, and may prefer to close some outstanding connections.¶
This could be done by checking available/consumed resources on a fixed schedule, by having a policy of only keeping a fixed number of connections open, by checking resources when activity occurs, or by some other cadence.¶
When existing connections should be closed, the recursive resolver should use a reasonable prioritization scheme to close outstanding connections.¶
One reasonable prioritization scheme would be:¶
- close outstanding
established sessions based on
E-last-activity[X] (oldest timestamp gets closed first)¶
Note that when resources are limited, a recursive resolver following this guidance may also choose not to initiate new connections for encrypted transport.¶
Some recursive resolvers looking to amortize connection costs, and to minimize latency MAY choose to synthesize queries to a particular resolver to keep a encrypted transport session active.¶
A recursive resolver that adopts this approach should try to align the synthesized queries with other optimizations.
For example, a recursive resolver that "pre-fetches" a particular resource record to keep its cache "hot" can send that query over an established encrypted transport session.¶