• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 # include "httpsrr.h"
32 #endif
33 
34 #ifndef CURL_DISABLE_DOH
35 
36 typedef enum {
37   DOH_OK,
38   DOH_DNS_BAD_LABEL,    /* 1 */
39   DOH_DNS_OUT_OF_RANGE, /* 2 */
40   DOH_DNS_LABEL_LOOP,   /* 3 */
41   DOH_TOO_SMALL_BUFFER, /* 4 */
42   DOH_OUT_OF_MEM,       /* 5 */
43   DOH_DNS_RDATA_LEN,    /* 6 */
44   DOH_DNS_MALFORMAT,    /* 7 */
45   DOH_DNS_BAD_RCODE,    /* 8 - no such name */
46   DOH_DNS_UNEXPECTED_TYPE,  /* 9 */
47   DOH_DNS_UNEXPECTED_CLASS, /* 10 */
48   DOH_NO_CONTENT,           /* 11 */
49   DOH_DNS_BAD_ID,           /* 12 */
50   DOH_DNS_NAME_TOO_LONG     /* 13 */
51 } DOHcode;
52 
53 typedef enum {
54   DNS_TYPE_A = 1,
55   DNS_TYPE_NS = 2,
56   DNS_TYPE_CNAME = 5,
57   DNS_TYPE_AAAA = 28,
58   DNS_TYPE_DNAME = 39,           /* RFC6672 */
59   DNS_TYPE_HTTPS = 65
60 } DNStype;
61 
62 /* one of these for each DoH request */
63 struct doh_probe {
64   curl_off_t easy_mid; /* multi id of easy handle doing the lookup */
65   DNStype dnstype;
66   unsigned char req_body[512];
67   size_t req_body_len;
68   struct dynbuf resp_body;
69 };
70 
71 enum doh_slot_num {
72   /* Explicit values for first two symbols so as to match hard-coded
73    * constants in existing code
74    */
75   DOH_SLOT_IPV4 = 0, /* make 'V4' stand out for readability */
76   DOH_SLOT_IPV6 = 1, /* 'V6' likewise */
77 
78   /* Space here for (possibly build-specific) additional slot definitions */
79 #ifdef USE_HTTPSRR
80   DOH_SLOT_HTTPS_RR = 2,     /* for HTTPS RR */
81 #endif
82 
83   /* for example */
84   /* #ifdef WANT_DOH_FOOBAR_TXT */
85   /*   DOH_PROBE_SLOT_FOOBAR_TXT, */
86   /* #endif */
87 
88   /* AFTER all slot definitions, establish how many we have */
89   DOH_SLOT_COUNT
90 };
91 
92 struct doh_probes {
93   struct curl_slist *req_hds;
94   struct doh_probe probe[DOH_SLOT_COUNT];
95   unsigned int pending; /* still outstanding probes */
96   int port;
97   const char *host;
98 };
99 
100 /*
101  * Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name
102  * and returns a 'Curl_addrinfo *' with the address information.
103  */
104 
105 struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
106                                const char *hostname,
107                                int port,
108                                int *waitp);
109 
110 CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
111                               struct Curl_dns_entry **dns);
112 
113 #define DOH_MAX_ADDR 24
114 #define DOH_MAX_CNAME 4
115 #define DOH_MAX_HTTPS 4
116 
117 struct dohaddr {
118   int type;
119   union {
120     unsigned char v4[4]; /* network byte order */
121     unsigned char v6[16];
122   } ip;
123 };
124 
125 #ifdef USE_HTTPSRR
126 
127 /*
128  * These may need escaping when found within an ALPN string
129  * value.
130  */
131 #define COMMA_CHAR                    ','
132 #define BACKSLASH_CHAR                '\\'
133 
134 struct dohhttps_rr {
135   uint16_t len; /* raw encoded length */
136   unsigned char *val; /* raw encoded octets */
137 };
138 #endif
139 
140 struct dohentry {
141   struct dynbuf cname[DOH_MAX_CNAME];
142   struct dohaddr addr[DOH_MAX_ADDR];
143   int numaddr;
144   unsigned int ttl;
145   int numcname;
146 #ifdef USE_HTTPSRR
147   struct dohhttps_rr https_rrs[DOH_MAX_HTTPS];
148   int numhttps_rrs;
149 #endif
150 };
151 
152 void Curl_doh_close(struct Curl_easy *data);
153 void Curl_doh_cleanup(struct Curl_easy *data);
154 
155 #ifdef UNITTESTS
156 UNITTEST DOHcode doh_req_encode(const char *host,
157                                 DNStype dnstype,
158                                 unsigned char *dnsp,  /* buffer */
159                                 size_t len,  /* buffer size */
160                                 size_t *olen);  /* output length */
161 UNITTEST DOHcode doh_resp_decode(const unsigned char *doh,
162                                  size_t dohlen,
163                                  DNStype dnstype,
164                                  struct dohentry *d);
165 
166 UNITTEST void de_init(struct dohentry *d);
167 UNITTEST void de_cleanup(struct dohentry *d);
168 #endif
169 
170 extern struct curl_trc_feat Curl_doh_trc;
171 
172 #else /* if DoH is disabled */
173 #define Curl_doh(a,b,c,d) NULL
174 #define Curl_doh_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
175 #endif
176 
177 #endif /* HEADER_CURL_DOH_H */
178