From 7f00146d0098e585727a219d4835800bc862b31d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 4 Oct 2018 11:57:29 +0200 Subject: doh: keep the IPv4 address in (original) network byte order Ideally this will fix the reversed order shown in SPARC tests: resp 8: Expected 127.0.0.1 got 1.0.0.127 Closes #3091 --- lib/doh.c | 19 +++++++++---------- lib/doh.h | 8 ++------ tests/unit/unit1650.c | 16 ++++++++-------- 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/lib/doh.c b/lib/doh.c index 178e474aa..019ac789c 100644 --- a/lib/doh.c +++ b/lib/doh.c @@ -358,7 +358,7 @@ static DOHcode store_a(unsigned char *doh, int index, struct dohentry *d) 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)); + memcpy(&a->ip.v4, &doh[index], 4); d->numaddr++; } return DOH_OK; @@ -369,9 +369,8 @@ static DOHcode store_aaaa(unsigned char *doh, int index, struct dohentry *d) /* silently ignore addresses over the limit */ if(d->numaddr < DOH_MAX_ADDR) { struct dohaddr *a = &d->addr[d->numaddr]; - struct addr6 *inet6p = &a->ip.v6; a->type = DNS_TYPE_AAAA; - memcpy(inet6p, &doh[index], 16); + memcpy(&a->ip.v6, &doh[index], 16); d->numaddr++; } return DOH_OK; @@ -649,9 +648,9 @@ static void showdoh(struct Curl_easy *data, for(i = 0; i < d->numaddr; i++) { struct dohaddr *a = &d->addr[i]; if(a->type == DNS_TYPE_A) { - infof(data, "DOH A: %d.%d.%d.%d\n", - a->ip.v4 & 0xff, (a->ip.v4>>8) & 0xff, - (a->ip.v4>>16) & 0xff, a->ip.v4 >>24); + infof(data, "DOH A: %u.%u.%u.%u\n", + a->ip.v4[0], a->ip.v4[1], + a->ip.v4[2], a->ip.v4[3]); } else if(a->type == DNS_TYPE_AAAA) { int j; @@ -663,8 +662,8 @@ static void showdoh(struct Curl_easy *data, len = 118; for(j = 0; j < 16; j += 2) { size_t l; - snprintf(ptr, len, "%s%02x%02x", j?":":"", d->addr[i].ip.v6.byte[j], - d->addr[i].ip.v6.byte[j + 1]); + snprintf(ptr, len, "%s%02x%02x", j?":":"", d->addr[i].ip.v6[j], + d->addr[i].ip.v6[j + 1]); l = strlen(ptr); len -= l; ptr += l; @@ -764,7 +763,7 @@ doh2ai(const struct dohentry *de, const char *hostname, int port) switch(ai->ai_family) { case AF_INET: addr = (void *)ai->ai_addr; /* storage area for this info */ - + DEBUGASSERT(sizeof(struct in_addr) == sizeof(de->addr[i].ip.v4)); memcpy(&addr->sin_addr, &de->addr[i].ip.v4, sizeof(struct in_addr)); addr->sin_family = (CURL_SA_FAMILY_T)addrtype; addr->sin_port = htons((unsigned short)port); @@ -773,7 +772,7 @@ doh2ai(const struct dohentry *de, const char *hostname, int port) #ifdef ENABLE_IPV6 case AF_INET6: addr6 = (void *)ai->ai_addr; /* storage area for this info */ - + DEBUGASSERT(sizeof(struct in6_addr) == sizeof(de->addr[i].ip.v6)); memcpy(&addr6->sin6_addr, &de->addr[i].ip.v6, sizeof(struct in6_addr)); addr6->sin6_family = (CURL_SA_FAMILY_T)addrtype; addr6->sin6_port = htons((unsigned short)port); diff --git a/lib/doh.h b/lib/doh.h index 96c1fa7c1..5f879e50e 100644 --- a/lib/doh.h +++ b/lib/doh.h @@ -67,10 +67,6 @@ typedef enum { #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 */ @@ -80,8 +76,8 @@ struct cnamestore { struct dohaddr { int type; union { - unsigned int v4; - struct addr6 v6; + unsigned char v4[4]; /* network byte order */ + unsigned char v6[16]; } ip; }; diff --git a/tests/unit/unit1650.c b/tests/unit/unit1650.c index 05024f9b2..723c06421 100644 --- a/tests/unit/unit1650.c +++ b/tests/unit/unit1650.c @@ -155,6 +155,7 @@ UNITTEST_START size_t size; unsigned char buffer[256]; size_t i; + unsigned char *p; for(i = 0; i < sizeof(req) / sizeof(req[0]); i++) { int rc = doh_encode(req[i].name, req[i].type, buffer, sizeof(buffer), &size); @@ -198,9 +199,8 @@ UNITTEST_START struct dohaddr *a; a = &d.addr[u]; if(resp[i].type == DNS_TYPE_A) { - snprintf(ptr, len, "%d.%d.%d.%d ", - a->ip.v4 & 0xff, (a->ip.v4>>8) & 0xff, - (a->ip.v4>>16) & 0xff, a->ip.v4 >>24); + p = &a->ip.v4[0]; + snprintf(ptr, len, "%u.%u.%u.%u ", p[0], p[1], p[2], p[3]); o = strlen(ptr); len -= o; ptr += o; @@ -209,8 +209,8 @@ UNITTEST_START int j; for(j = 0; j < 16; j += 2) { size_t l; - snprintf(ptr, len, "%s%02x%02x", j?":":"", a->ip.v6.byte[j], - a->ip.v6.byte[j + 1]); + snprintf(ptr, len, "%s%02x%02x", j?":":"", a->ip.v6[j], + a->ip.v6[j + 1]); l = strlen(ptr); len -= l; ptr += l; @@ -270,9 +270,9 @@ UNITTEST_START DNS_TYPE_A, &d); fail_if(d.numaddr != 1, "missing address"); a = &d.addr[0]; - snprintf((char *)buffer, sizeof(buffer), "%d.%d.%d.%d", - a->ip.v4 & 0xff, (a->ip.v4>>8) & 0xff, - (a->ip.v4>>16) & 0xff, a->ip.v4 >>24); + p = &a->ip.v4[0]; + snprintf((char *)buffer, sizeof(buffer), + "%u.%u.%u.%u", p[0], p[1], p[2], p[3]); if(rc || strcmp((char *)buffer, "127.0.0.1")) { fprintf(stderr, "bad address decoded: %s, rc == %d\n", buffer, rc); return 7; -- cgit v1.2.1