about summary refs log tree commit diff
path: root/lisp/dns/client.lisp
blob: 0f355589db13c8276f96e688ae83111047d1d76b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
;; Implementation of a DoH-client, see RFC 8484 (DNS Queries over
;; HTTPS (DoH))

(in-package #:dns)

;;    The DoH client is configured with a URI Template [RFC6570]
(defvar *doh-base-url* "https://dns.google/dns-query"
  "Base URL of the service providing DNS-over-HTTP(S). Defaults to the
  Google-hosted API.")

(defun lookup-generic (name type)
  (multiple-value-bind (stream)
      (drakma:http-request *doh-base-url*
                           :decode-content t
                           :want-stream t
                           :parameters `(("type" . ,type)
                                         ("name" . ,name)
                                         ("ct" . "application/dns-message")))
    (read-binary 'dns-message stream)))

(defun lookup-txt (name)
  "Look up the TXT records at NAME."
  (lookup-generic name "TXT"))

(defun lookup-mx (name)
  "Look up the MX records at NAME."
  (lookup-generic name "MX"))


;;    The URI Template defined in this document is processed without any
;;    variables when the HTTP method is POST.  When the HTTP method is GET,
;;    the single variable "dns" is defined as the content of the DNS
;;    request (as described in Section 6), encoded with base64url
;;    [RFC4648].

;;    When using the POST method, the DNS query is included as the message
;;    body of the HTTP request, and the Content-Type request header field
;;    indicates the media type of the message.  POSTed requests are
;;    generally smaller than their GET equivalents.

;;    Using the GET method is friendlier to many HTTP cache
;;    implementations.

;;    The DoH client SHOULD include an HTTP Accept request header field to
;;    indicate what type of content can be understood in response.
;;    Irrespective of the value of the Accept request header field, the
;;    client MUST be prepared to process "application/dns-message" (as
;;    described in Section 6) responses but MAY also process other DNS-
;;    related media types it receives.

;;    In order to maximize HTTP cache friendliness, DoH clients using media
;;    formats that include the ID field from the DNS message header, such
;;    as "application/dns-message", SHOULD use a DNS ID of 0 in every DNS
;;    request.  HTTP correlates the request and response, thus eliminating
;;    the need for the ID in a media type such as "application/dns-
;;    message".  The use of a varying DNS ID can cause semantically
;;    equivalent DNS queries to be cached separately.

;;    DoH clients can use HTTP/2 padding and compression [RFC7540] in the
;;    same way that other HTTP/2 clients use (or don't use) them.

;; 4.1.1.  HTTP Request Examples

;;    These examples use HTTP/2-style formatting from [RFC7540].

;;    These examples use a DoH service with a URI Template of
;;    "https://dnsserver.example.net/dns-query{?dns}" to resolve IN A
;;    records.

;;    The requests are represented as bodies with media type "application/
;;    dns-message".

;;    The first example request uses GET to request "www.example.com".

;;    :method = GET
;;    :scheme = https
;;    :authority = dnsserver.example.net
;;    :path = /dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
;;    accept = application/dns-message

;;    Finally, a GET-based query for "a.62characterlabel-makes-base64url-
;;    distinct-from-standard-base64.example.com" is shown as an example to
;;    emphasize that the encoding alphabet of base64url is different than
;;    regular base64 and that padding is omitted.

;;    The only response type defined in this document is "application/dns-
;;    message", but it is possible that other response formats will be
;;    defined in the future.  A DoH server MUST be able to process
;;    "application/dns-message" request messages.

;;    Each DNS request-response pair is mapped to one HTTP exchange.

;;    DNS response codes indicate either success or failure for the DNS
;;    query.  A successful HTTP response with a 2xx status code (see
;;    Section 6.3 of [RFC7231]) is used for any valid DNS response,

;;    HTTP responses with non-successful HTTP status codes do not contain
;;    replies to the original DNS question in the HTTP request.  DoH
;;    clients need to use the same semantic processing of non-successful
;;    HTTP status codes as other HTTP clients.

;; 4.2.2.  HTTP Response Example

;;    This is an example response for a query for the IN AAAA records for
;;    "www.example.com" with recursion turned on.  The response bears one
;;    answer record with an address of 2001:db8:abcd:12:1:2:3:4 and a TTL
;;    of 3709 seconds.

;;    :status = 200
;;    content-type = application/dns-message
;;    content-length = 61
;;    cache-control = max-age=3709

;;    <61 bytes represented by the following hex encoding>
;;    00 00 81 80 00 01 00 01  00 00 00 00 03 77 77 77
;;    07 65 78 61 6d 70 6c 65  03 63 6f 6d 00 00 1c 00
;;    01 c0 0c 00 1c 00 01 00  00 0e 7d 00 10 20 01 0d
;;    b8 ab cd 00 12 00 01 00  02 00 03 00 04

;;    This protocol MUST be used with the https URI scheme [RFC7230].

;;    In particular, DoH servers SHOULD assign an explicit HTTP freshness
;;    lifetime (see Section 4.2 of [RFC7234]) so that the DoH client is
;;    more likely to use fresh DNS data.  This requirement is due to HTTP
;;    caches being able to assign their own heuristic freshness (such as
;;    that described in Section 4.2.2 of [RFC7234]), which would take
;;    control of the cache contents out of the hands of the DoH server.


;;    The assigned freshness lifetime of a DoH HTTP response MUST be less
;;    than or equal to the smallest TTL in the Answer section of the DNS
;;    response.  A freshness lifetime equal to the smallest TTL in the
;;    Answer section is RECOMMENDED.  For example, if a HTTP response
;;    carries three RRsets with TTLs of 30, 600, and 300, the HTTP
;;    freshness lifetime should be 30 seconds (which could be specified as
;;    "Cache-Control: max-age=30").  This requirement helps prevent expired
;;    RRsets in messages in an HTTP cache from unintentionally being
;;    served.

;;    If the DNS response has no records in the Answer section, and the DNS
;;    response has an SOA record in the Authority section, the response
;;    freshness lifetime MUST NOT be greater than the MINIMUM field from
;;    that SOA record (see [RFC2308]).

;;    DoH clients MUST account for the Age response header field's value
;;    [RFC7234] when calculating the DNS TTL of a response.  For example,
;;    if an RRset is received with a DNS TTL of 600, but the Age header
;;    field indicates that the response has been cached for 250 seconds,
;;    the remaining lifetime of the RRset is 350 seconds.  This requirement
;;    applies to both DoH client HTTP caches and DoH client DNS caches.

;;    Those features were introduced to HTTP in HTTP/2 [RFC7540].
;;    Earlier versions of HTTP are capable of conveying the semantic
;;    requirements of DoH but may result in very poor performance.

;;    In order to maximize interoperability, DoH clients and DoH servers
;;    MUST support the "application/dns-message" media type.

;;    The data payload for the "application/dns-message" media type is a
;;    single message of the DNS on-the-wire format defined in Section 4.2.1
;;    of [RFC1035], which in turn refers to the full wire format defined in
;;    Section 4.1 of that RFC.

;;    This media type restricts the maximum size of the DNS message to
;;    65535 bytes.

;;    When using the GET method, the data payload for this media type MUST
;;    be encoded with base64url [RFC4648] and then provided as a variable
;;    named "dns" to the URI Template expansion.  Padding characters for
;;    base64url MUST NOT be included.

;;    When using the POST method, the data payload for this media type MUST
;;    NOT be encoded and is used directly as the HTTP message body.