xref: /curl/lib/doh.h (revision 435dd8aa)
1 #ifndef HEADER_CURL_DOH_H
2 #define HEADER_CURL_DOH_H
3 /***************************************************************************
4  *                                  _   _ ____  _
5  *  Project                     ___| | | |  _ \| |
6  *                             / __| | | | |_) | |
7  *                            | (__| |_| |  _ <| |___
8  *                             \___|\___/|_| \_\_____|
9  *
10  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
11  *
12  * This software is licensed as described in the file COPYING, which
13  * you should have received as part of this distribution. The terms
14  * are also available at https://curl.se/docs/copyright.html.
15  *
16  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
17  * copies of the Software, and permit persons to whom the Software is
18  * furnished to do so, under the terms of the COPYING file.
19  *
20  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21  * KIND, either express or implied.
22  *
23  * SPDX-License-Identifier: curl
24  *
25  ***************************************************************************/
26 
27 #include "urldata.h"
28 #include "curl_addrinfo.h"
29 #ifdef USE_HTTPSRR
30 # include <stdint.h>
31 #endif
32 
33 #ifndef CURL_DISABLE_DOH
34 
35 typedef enum {
36   DOH_OK,
37   DOH_DNS_BAD_LABEL,    /* 1 */
38   DOH_DNS_OUT_OF_RANGE, /* 2 */
39   DOH_DNS_LABEL_LOOP,   /* 3 */
40   DOH_TOO_SMALL_BUFFER, /* 4 */
41   DOH_OUT_OF_MEM,       /* 5 */
42   DOH_DNS_RDATA_LEN,    /* 6 */
43   DOH_DNS_MALFORMAT,    /* 7 */
44   DOH_DNS_BAD_RCODE,    /* 8 - no such name */
45   DOH_DNS_UNEXPECTED_TYPE,  /* 9 */
46   DOH_DNS_UNEXPECTED_CLASS, /* 10 */
47   DOH_NO_CONTENT,           /* 11 */
48   DOH_DNS_BAD_ID,           /* 12 */
49   DOH_DNS_NAME_TOO_LONG     /* 13 */
50 } DOHcode;
51 
52 typedef enum {
53   DNS_TYPE_A = 1,
54   DNS_TYPE_NS = 2,
55   DNS_TYPE_CNAME = 5,
56   DNS_TYPE_AAAA = 28,
57   DNS_TYPE_DNAME = 39,           /* RFC6672 */
58   DNS_TYPE_HTTPS = 65
59 } DNStype;
60 
61 /* one of these for each DoH request */
62 struct doh_probe {
63   curl_off_t easy_mid; /* multi id of easy handle doing the lookup */
64   DNStype dnstype;
65   unsigned char req_body[512];
66   size_t req_body_len;
67   struct dynbuf resp_body;
68 };
69 
70 enum doh_slot_num {
71   /* Explicit values for first two symbols so as to match hard-coded
72    * constants in existing code
73    */
74   DOH_SLOT_IPV4 = 0, /* make 'V4' stand out for readability */
75   DOH_SLOT_IPV6 = 1, /* 'V6' likewise */
76 
77   /* Space here for (possibly build-specific) additional slot definitions */
78 #ifdef USE_HTTPSRR
79   DOH_SLOT_HTTPS_RR = 2,     /* for HTTPS RR */
80 #endif
81 
82   /* for example */
83   /* #ifdef WANT_DOH_FOOBAR_TXT */
84   /*   DOH_PROBE_SLOT_FOOBAR_TXT, */
85   /* #endif */
86 
87   /* AFTER all slot definitions, establish how many we have */
88   DOH_SLOT_COUNT
89 };
90 
91 struct doh_probes {
92   struct curl_slist *req_hds;
93   struct doh_probe probe[DOH_SLOT_COUNT];
94   unsigned int pending; /* still outstanding probes */
95   int port;
96   const char *host;
97 };
98 
99 /*
100  * Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name
101  * and returns a 'Curl_addrinfo *' with the address information.
102  */
103 
104 struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
105                                const char *hostname,
106                                int port,
107                                int *waitp);
108 
109 CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
110                               struct Curl_dns_entry **dns);
111 
112 #define DOH_MAX_ADDR 24
113 #define DOH_MAX_CNAME 4
114 #define DOH_MAX_HTTPS 4
115 
116 struct dohaddr {
117   int type;
118   union {
119     unsigned char v4[4]; /* network byte order */
120     unsigned char v6[16];
121   } ip;
122 };
123 
124 #ifdef USE_HTTPSRR
125 
126 /*
127  * These are the code points for DNS wire format SvcParams as
128  * per draft-ietf-dnsop-svcb-https
129  * Not all are supported now, and even those that are may need
130  * more work in future to fully support the spec.
131  */
132 #define HTTPS_RR_CODE_ALPN            0x01
133 #define HTTPS_RR_CODE_NO_DEF_ALPN     0x02
134 #define HTTPS_RR_CODE_PORT            0x03
135 #define HTTPS_RR_CODE_IPV4            0x04
136 #define HTTPS_RR_CODE_ECH             0x05
137 #define HTTPS_RR_CODE_IPV6            0x06
138 
139 /*
140  * These may need escaping when found within an ALPN string
141  * value.
142  */
143 #define COMMA_CHAR                    ','
144 #define BACKSLASH_CHAR                '\\'
145 
146 struct dohhttps_rr {
147   uint16_t len; /* raw encoded length */
148   unsigned char *val; /* raw encoded octets */
149 };
150 #endif
151 
152 struct dohentry {
153   struct dynbuf cname[DOH_MAX_CNAME];
154   struct dohaddr addr[DOH_MAX_ADDR];
155   int numaddr;
156   unsigned int ttl;
157   int numcname;
158 #ifdef USE_HTTPSRR
159   struct dohhttps_rr https_rrs[DOH_MAX_HTTPS];
160   int numhttps_rrs;
161 #endif
162 };
163 
164 void Curl_doh_close(struct Curl_easy *data);
165 void Curl_doh_cleanup(struct Curl_easy *data);
166 
167 #ifdef UNITTESTS
168 UNITTEST DOHcode doh_req_encode(const char *host,
169                                 DNStype dnstype,
170                                 unsigned char *dnsp,  /* buffer */
171                                 size_t len,  /* buffer size */
172                                 size_t *olen);  /* output length */
173 UNITTEST DOHcode doh_resp_decode(const unsigned char *doh,
174                                  size_t dohlen,
175                                  DNStype dnstype,
176                                  struct dohentry *d);
177 
178 UNITTEST void de_init(struct dohentry *d);
179 UNITTEST void de_cleanup(struct dohentry *d);
180 #endif
181 
182 extern struct curl_trc_feat Curl_doh_trc;
183 
184 #else /* if DoH is disabled */
185 #define Curl_doh(a,b,c,d) NULL
186 #define Curl_doh_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
187 #endif
188 
189 #endif /* HEADER_CURL_DOH_H */
190