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