aboutsummaryrefslogtreecommitdiff
path: root/lib/doh.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2018-06-19 16:08:05 +0200
committerDaniel Stenberg <daniel@haxx.se>2018-09-06 09:17:25 +0200
commitf2b1a1897537d1915ac2f840b13a8991018755c4 (patch)
tree1b431cf3673798d4ac985507332fd99c5cbf661a /lib/doh.c
parent5ffbb63e4271b7df05f0bfc31d0696745f028e76 (diff)
DOH: add test case 1650 and 2100
Diffstat (limited to 'lib/doh.c')
-rw-r--r--lib/doh.c92
1 files changed, 27 insertions, 65 deletions
diff --git a/lib/doh.c b/lib/doh.c
index 5d1cd3b78..33b3e06c9 100644
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -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++) {