std/http/doh

std/http/src/doh.trb

DNS over HTTPS (RFC 8484): DohResolver asks one name server with a POST to its https endpoint - the same two calls of std/dns around another pipe as TlsResolver of std/tls makes (docs/design/DNS.md sections 2 and 7).

type DohResolver

type DohResolver with NameResolver

DNS over HTTPS (RFC 8484): the lookups of std/network's Resolver, asked of one name server as a POST of the query to its endpoint, with the server authenticated by the host of the URL its certificate has to carry.

const server = Uri.tryFrom("https://dns.example.test/dns-query")?
const resolver = DohResolver(server)
const records = resolver.lookup(DomainName.tryFrom("example.test")?, RecordType.Aaaa).await()?

The query carries the identifier 0 (RFC 8484 section 4.1: every query of one connection may be answered from a cache of the same response, so the identifier does not tell them apart) and the Content-Type and Accept of application/dns-message; the response is read from the body of a 2xx answer, at most 65535 bytes of it. Every lookup opens a connection of its own and closes it with the answer: keeping one open for the next question is a later refinement. Times are milliseconds, because a field's default is a constant and a Duration is none.

field url

url: Uri

The server's endpoint, an https URL such as https://dns.example.test/dns-query; another scheme is refused.

field tls

tls: TlsSettings = TlsSettings()

What the client trusts: the platform's roots by default.

field attemptMilliseconds

attemptMilliseconds: Int = 5000

How long connecting, the handshake and the answer may take together.

fn lookup

fn lookup(name: DomainName, recordType: RecordType): Task<Result<List<Record>, NetworkError>>

The records of recordType that name has, CNAME chains followed within the answer.

Errors

  • NetworkError that isHostNotFound() where the name does not exist (NXDOMAIN), and isNameServerFailure() where the server answered SERVFAIL, REFUSED or NOTIMP.
  • Every failure of DohResolver.exchange.

fn exchange

fn exchange(name: DomainName, recordType: RecordType): Task<Result<Message, NetworkError>>

The whole response to a query for recordType at name, with the identifier 0 of RFC 8484 section 4.1.

Errors

  • NetworkError that isTimedOut() where the attempt's time passed, isCertificateRejected() where the server could not prove the host of the URL, and isNameServerFailure() where the URL is not an https one, the server answered a status that is not a success, or its body is not the response.
  • The failure of the connection or of the TLS handshake under an HttpError, as the NetworkError it carries.