diff options
author | Daniel Stenberg <daniel@haxx.se> | 2018-06-19 16:08:05 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2018-09-06 09:17:25 +0200 |
commit | f2b1a1897537d1915ac2f840b13a8991018755c4 (patch) | |
tree | 1b431cf3673798d4ac985507332fd99c5cbf661a /lib | |
parent | 5ffbb63e4271b7df05f0bfc31d0696745f028e76 (diff) |
DOH: add test case 1650 and 2100
Diffstat (limited to 'lib')
-rw-r--r-- | lib/doh.c | 92 | ||||
-rw-r--r-- | lib/doh.h | 65 |
2 files changed, 92 insertions, 65 deletions
@@ -38,31 +38,6 @@ #define DNS_CLASS_IN 0x01 #define DOH_MAX_RESPONSE_SIZE 3000 /* bytes */ -typedef enum { - DNS_TYPE_A = 1, - DNS_TYPE_NS = 2, - DNS_TYPE_CNAME = 5, - DNS_TYPE_AAAA = 28 -} DNStype; - -#define MAX_ADDR 24 - -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 */ -} DOHcode; - static const char * const errors[]={ "", "Bad label", @@ -86,11 +61,17 @@ static const char *doh_strerror(DOHcode code) return "bad error code"; } -static DOHcode doh_encode(const char *host, - DNStype dnstype, - unsigned char *dnsp, /* buffer */ - size_t len, /* buffer size */ - size_t *olen) /* output length */ +#ifdef DEBUGBUILD +#define UNITTEST +#else +#define UNITTEST static +#endif + +UNITTEST DOHcode doh_encode(const char *host, + DNStype dnstype, + unsigned char *dnsp, /* buffer */ + size_t len, /* buffer size */ + size_t *olen) /* output length */ { size_t hostlen = strlen(host); unsigned char *orig = dnsp; @@ -123,9 +104,11 @@ static DOHcode doh_encode(const char *host, } else labellen = strlen(hostp); - if(labellen > 63) + if(labellen > 63) { /* too long label, error out */ + *olen = 0; return DOH_DNS_BAD_LABEL; + } *dnsp++ = (unsigned char)labellen; memcpy(dnsp, hostp, labellen); dnsp += labellen; @@ -363,36 +346,10 @@ static unsigned int get32bit(unsigned char *doh, int index) (doh[index + 2] << 8) | doh[index + 3]; } -struct addr6 { - unsigned char byte[16]; -}; - -struct cnamestore { - size_t len; /* length of cname */ - char *alloc; /* allocated pointer */ - size_t allocsize; /* allocated size */ -}; - -struct dohaddr { - int type; - union { - unsigned int v4; - struct addr6 v6; - } ip; -}; - -struct dohentry { - unsigned int ttl; - int numaddr; - struct dohaddr addr[MAX_ADDR]; - int numcname; - struct cnamestore cname[MAX_ADDR]; -}; - static DOHcode store_a(unsigned char *doh, int index, struct dohentry *d) { /* silently ignore addresses over the limit */ - if(d->numaddr < MAX_ADDR) { + if(d->numaddr < DOH_MAX_ADDR) { struct dohaddr *a = &d->addr[d->numaddr]; a->type = DNS_TYPE_A; a->ip.v4 = ntohl(get32bit(doh, index)); @@ -404,7 +361,7 @@ static DOHcode store_a(unsigned char *doh, int index, struct dohentry *d) static DOHcode store_aaaa(unsigned char *doh, int index, struct dohentry *d) { /* silently ignore addresses over the limit */ - if(d->numaddr < MAX_ADDR) { + if(d->numaddr < DOH_MAX_ADDR) { struct dohaddr *a = &d->addr[d->numaddr]; struct addr6 *inet6p = &a->ip.v6; a->type = DNS_TYPE_AAAA; @@ -445,9 +402,14 @@ static DOHcode store_cname(unsigned char *doh, unsigned int index, struct dohentry *d) { - struct cnamestore *c = &d->cname[d->numcname++]; + struct cnamestore *c; unsigned int loop = 128; /* a valid DNS name can never loop this much */ unsigned char length; + + if(d->numcname == DOH_MAX_CNAME) + return DOH_OK; /* skip! */ + + c = &d->cname[d->numcname++]; do { if(index >= dohlen) return DOH_DNS_OUT_OF_RANGE; @@ -530,10 +492,10 @@ static DOHcode rdata(unsigned char *doh, return DOH_OK; } -static DOHcode doh_decode(unsigned char *doh, - size_t dohlen, - DNStype dnstype, - struct dohentry *d) +UNITTEST DOHcode doh_decode(unsigned char *doh, + size_t dohlen, + DNStype dnstype, + struct dohentry *d) { unsigned char rcode; unsigned short qdcount; @@ -824,7 +786,7 @@ static const char *type2name(DNStype dnstype) return (dnstype == DNS_TYPE_A)?"A":"AAAA"; } -static void de_cleanup(struct dohentry *d) +UNITTEST void de_cleanup(struct dohentry *d) { int i = 0; for(i = 0; i < d->numcname; i++) { @@ -41,4 +41,69 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn, int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks); +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 */ +} DOHcode; + +typedef enum { + DNS_TYPE_A = 1, + DNS_TYPE_NS = 2, + DNS_TYPE_CNAME = 5, + DNS_TYPE_AAAA = 28 +} DNStype; + +#define DOH_MAX_ADDR 24 +#define DOH_MAX_CNAME 4 + +struct addr6 { + unsigned char byte[16]; +}; + +struct cnamestore { + size_t len; /* length of cname */ + char *alloc; /* allocated pointer */ + size_t allocsize; /* allocated size */ +}; + +struct dohaddr { + int type; + union { + unsigned int v4; + struct addr6 v6; + } ip; +}; + +struct dohentry { + unsigned int ttl; + int numaddr; + struct dohaddr addr[DOH_MAX_ADDR]; + int numcname; + struct cnamestore cname[DOH_MAX_CNAME]; +}; + + +#ifdef DEBUGBUILD +DOHcode doh_encode(const char *host, + DNStype dnstype, + unsigned char *dnsp, /* buffer */ + size_t len, /* buffer size */ + size_t *olen); /* output length */ +DOHcode doh_decode(unsigned char *doh, + size_t dohlen, + DNStype dnstype, + struct dohentry *d); +void de_cleanup(struct dohentry *d); +#endif #endif |