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 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
#ifndef HEADER_CURL_DOH_H
#define HEADER_CURL_DOH_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "urldata.h"
#include "curl_addrinfo.h"
#ifdef USE_HTTPSRR
# include <stdint.h>
# include "httpsrr.h"
#endif
#ifndef CURL_DISABLE_DOH
typedef enum {
DOH_OK,
DOH_DNS_BAD_LABEL, /* 1 */
DOH_DNS_OUT_OF_RANGE, /* 2 */
DOH_DNS_LABEL_LOOP, /* 3 */
DOH_TOO_SMALL_BUFFER, /* 4 */
DOH_OUT_OF_MEM, /* 5 */
DOH_DNS_RDATA_LEN, /* 6 */
DOH_DNS_MALFORMAT, /* 7 */
DOH_DNS_BAD_RCODE, /* 8 - no such name */
DOH_DNS_UNEXPECTED_TYPE, /* 9 */
DOH_DNS_UNEXPECTED_CLASS, /* 10 */
DOH_NO_CONTENT, /* 11 */
DOH_DNS_BAD_ID, /* 12 */
DOH_DNS_NAME_TOO_LONG /* 13 */
} DOHcode;
typedef enum {
DNS_TYPE_A = 1,
DNS_TYPE_NS = 2,
DNS_TYPE_CNAME = 5,
DNS_TYPE_AAAA = 28,
DNS_TYPE_DNAME = 39, /* RFC6672 */
DNS_TYPE_HTTPS = 65
} DNStype;
enum doh_slot_num {
/* Explicit values for first two symbols so as to match hard-coded
* constants in existing code
*/
DOH_SLOT_IPV4 = 0, /* make 'V4' stand out for readability */
DOH_SLOT_IPV6 = 1, /* 'V6' likewise */
/* Space here for (possibly build-specific) additional slot definitions */
#ifdef USE_HTTPSRR
DOH_SLOT_HTTPS_RR = 2, /* for HTTPS RR */
#endif
/* for example */
/* #ifdef WANT_DOH_FOOBAR_TXT */
/* DOH_PROBE_SLOT_FOOBAR_TXT, */
/* #endif */
/* AFTER all slot definitions, establish how many we have */
DOH_SLOT_COUNT
};
#define CURL_EZM_DOH_PROBE "ezm:doh-p"
/* the largest one we can make, based on RFCs 1034, 1035 */
#define DOH_MAX_DNSREQ_SIZE (256 + 16)
/* each DoH probe request has this
* as easy meta for CURL_EZM_DOH_PROBE */
struct doh_request {
unsigned char req_body[DOH_MAX_DNSREQ_SIZE];
struct curl_slist *req_hds;
struct dynbuf resp_body;
size_t req_body_len;
DNStype dnstype;
};
struct doh_response {
unsigned int probe_mid;
struct dynbuf body;
DNStype dnstype;
CURLcode result;
};
/* each transfer firing off DoH requests has this
* as easy meta for CURL_EZM_DOH_MASTER */
struct doh_probes {
struct doh_response probe_resp[DOH_SLOT_COUNT];
unsigned int pending; /* still outstanding probes */
int port;
const char *host;
};
/*
* Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name
* and returns a 'Curl_addrinfo *' with the address information.
*/
struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
const char *hostname,
int port,
int ip_version,
int *waitp);
CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
struct Curl_dns_entry **dns);
#define DOH_MAX_ADDR 24
#define DOH_MAX_CNAME 4
#define DOH_MAX_HTTPS 4
struct dohaddr {
int type;
union {
unsigned char v4[4]; /* network byte order */
unsigned char v6[16];
} ip;
};
#ifdef USE_HTTPSRR
/*
* These may need escaping when found within an ALPN string
* value.
*/
#define COMMA_CHAR ','
#define BACKSLASH_CHAR '\\'
struct dohhttps_rr {
uint16_t len; /* raw encoded length */
unsigned char *val; /* raw encoded octets */
};
#endif
struct dohentry {
struct dynbuf cname[DOH_MAX_CNAME];
struct dohaddr addr[DOH_MAX_ADDR];
int numaddr;
unsigned int ttl;
int numcname;
#ifdef USE_HTTPSRR
struct dohhttps_rr https_rrs[DOH_MAX_HTTPS];
int numhttps_rrs;
#endif
};
void Curl_doh_close(struct Curl_easy *data);
void Curl_doh_cleanup(struct Curl_easy *data);
#ifdef UNITTESTS
UNITTEST DOHcode doh_req_encode(const char *host,
DNStype dnstype,
unsigned char *dnsp, /* buffer */
size_t len, /* buffer size */
size_t *olen); /* output length */
UNITTEST DOHcode doh_resp_decode(const unsigned char *doh,
size_t dohlen,
DNStype dnstype,
struct dohentry *d);
UNITTEST void de_init(struct dohentry *d);
UNITTEST void de_cleanup(struct dohentry *d);
#endif
#else /* if DoH is disabled */
#define Curl_doh(a,b,c,d,e) NULL
#define Curl_doh_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
#endif
#endif /* HEADER_CURL_DOH_H */
|