]> granicus.if.org Git - curl/commitdiff
doh: keep the IPv4 address in (original) network byte order
authorDaniel Stenberg <daniel@haxx.se>
Thu, 4 Oct 2018 09:57:29 +0000 (11:57 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 5 Oct 2018 20:15:34 +0000 (22:15 +0200)
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
lib/doh.h
tests/unit/unit1650.c

index 178e474aa2f6b7335a99157811d37e0d6ae7f077..019ac789c0429149cef92f8c3775ad4041ea397d 100644 (file)
--- 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);
index 96c1fa7c171dadc344443306d5aa2f704c7e1fd6..5f879e50e05dd8f63a1eb5a99459ea7574d77535 100644 (file)
--- 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;
 };
 
index 05024f9b24d4bf2b469f9b34d90e9eecc5946ac4..723c0642168753e8b8a2363e1935179d39a995c6 100644 (file)
@@ -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;