diff options
Diffstat (limited to 'lib/doh.c')
-rw-r--r-- | lib/doh.c | 92 |
1 files changed, 27 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++) { |