resolver: Actually set port in resulting ca's
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 23 Oct 2014 22:49:17 +0000 (23:49 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 23 Oct 2014 23:16:27 +0000 (00:16 +0100)
This got broken in 2093fb5c `comm etc.: Provide comm_addr_equal'.

We mistakenly removed the code that copied the port from q, along with
the code that copied the adns answer from ra.  (The sockaddr that
comes back from adns obviously doesn't have a port number in it.)

As a result all actual DNS resolutions would result in an unuseable
sockaddr with port==0.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
resolver.c

index 6f6588f..2bc7d06 100644 (file)
@@ -134,20 +134,23 @@ static void resolver_afterpoll(void *sst, struct pollfd *fds, int nfds)
                    struct comm_addr *ca=&ca_buf[wslot];
                    ca->comm=q->comm;
                    ca->ix=-1;
+                   assert(ra->len <= (int)sizeof(ca->ia));
+                   memcpy(&ca->ia,&ra->addr,ra->len);
                    switch (ra->addr.sa.sa_family) {
                    case AF_INET:
                        assert(ra->len == sizeof(ca->ia.sin));
+                       ca->ia.sin.sin_port=htons(q->port);
                        break;
 #ifdef CONFIG_IPV6
                    case AF_INET6:
                        assert(ra->len == sizeof(ca->ia.sin6));
+                       ca->ia.sin6.sin6_port=htons(q->port);
                        break;
 #endif /*CONFIG_IPV6*/
                    default:
                        /* silently skip unexpected AFs from adns */
                        continue;
                    }
-                   memcpy(&ca->ia,&ra->addr,ra->len);
                    wslot++;
                }
                q->answer(q->cst,ca_buf,wslot,total,q->name,0);