]> git.saurik.com Git - apple/libresolv.git/commitdiff
libresolv-25.0.2.tar.gz mac-os-x-1055 mac-os-x-1056 mac-os-x-1057 mac-os-x-1058 v25.0.2
authorApple <opensource@apple.com>
Mon, 4 Aug 2008 15:45:09 +0000 (15:45 +0000)
committerApple <opensource@apple.com>
Mon, 4 Aug 2008 15:45:09 +0000 (15:45 +0000)
dns.c
res_init.c
res_send.c

diff --git a/dns.c b/dns.c
index fa5ddfa0471ab39b61294060ac848437f3917acb..7c5ceb425029576166436d3ea44db690f275d0bc 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -882,7 +882,7 @@ _pdns_get_default_handles(sdns_handle_t *sdns, pdns_handle_t ***pdns)
 }
 
 static uint32_t
-_pdns_get_handles_for_name(sdns_handle_t *sdns, const char *name, pdns_handle_t ***pdns)
+_pdns_get_handles_for_name(sdns_handle_t *sdns, const char *name, uint32_t nlabels, pdns_handle_t ***pdns)
 {
        char *p, *vname;
        int i, j, k, count;
@@ -906,6 +906,9 @@ _pdns_get_handles_for_name(sdns_handle_t *sdns, const char *name, pdns_handle_t
                {
                        if (sdns->client[i]->name == NULL) continue;
 
+                       /* Special case:  Don't send to ".local[.]" queries to mDNSResponder if nlabels > 2 */
+                       if ((nlabels > 2) && (sdns->client[i]->flags & DNS_FLAG_FORWARD_TO_MDNSRESPONDER) && (!strcasecmp(sdns->client[i]->name, "local"))) continue;
+
                        if (!strcasecmp(sdns->client[i]->name, p))
                        {
                                if (count == 0)
@@ -1248,7 +1251,7 @@ _pdns_delay(sdns_handle_t *sdns)
                tick = time(NULL);
                /*
                 * Subsequent threads sleep for the remaining duration.
-                * We add one to round up the interval since our garnularity is coarse.
+                * We add one to round up the interval since our granularity is coarse.
                 */
                snooze = 1 + (sdns->dns_delay - tick);
                if (snooze < 0) snooze = 0;
@@ -1355,7 +1358,7 @@ _pdns_search(sdns_handle_t *sdns, pdns_handle_t *pdns, const char *name, uint32_
 }
 
 static int
-_sdns_send(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t type, uint32_t fqdn, char *buf, uint32_t len, struct sockaddr *from, uint32_t *fromlen, int *min)
+_sdns_send(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t type, uint32_t fqdn, char *buf, uint32_t len, struct sockaddr *from, uint32_t *fromlen, uint32_t nlabels, int *min)
 {
        char *qname;
        pdns_handle_t **pdns;
@@ -1370,7 +1373,7 @@ _sdns_send(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t type,
        *min = -1;
        m = -1;
 
-       pdns_count = _pdns_get_handles_for_name(sdns, name, &pdns);
+       pdns_count = _pdns_get_handles_for_name(sdns, name, nlabels, &pdns);
 
        if (pdns_count == 0) return -1;
 
@@ -1409,7 +1412,7 @@ __private_extern__ int
 _sdns_search(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t type, uint32_t fqdn, uint32_t recurse, char *buf, uint32_t len, struct sockaddr *from, uint32_t *fromlen, int *min)
 {
        pdns_handle_t *primary, **pdns;
-       int i, n, ndots, status;
+       int i, n, ndots, nlabels, status;
        int m, tmin, minstate;
        char *dot, *qname;
        uint32_t pdns_count;
@@ -1452,6 +1455,9 @@ _sdns_search(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t typ
        /* the last dot is the last character, name is fully qualified */
        if ((fqdn == 0) && (dot != NULL) && (*(dot + 1) == '\0')) fqdn = 1;
 
+       /* number of labels */
+       nlabels = n + 1 - fqdn;
+
        /*
         * If n >= ndots, or it's a FQDN, or if it's a PTR query,
         * we try a query with the name "as is".
@@ -1459,7 +1465,7 @@ _sdns_search(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t typ
        if ((n >= ndots) || (fqdn == 1) || (type == ns_t_ptr))
        {
                tmin = -1;
-               status = _sdns_send(sdns, name, class, type, fqdn, buf, len, from, fromlen, &tmin);
+               status = _sdns_send(sdns, name, class, type, fqdn, buf, len, from, fromlen, nlabels, &tmin);
                if (status > 0) return status;
 
                if (tmin < 0) minstate = -1;
index 0057cbb2f5ea10f935c4cea39ca6934a1859e999..bdb3845ee156f471b52432210c6485e943662d8a 100644 (file)
@@ -134,7 +134,6 @@ res_state
 res_build_start(res_state x)
 {
        res_state res;
-       int rf;
 
        res = NULL;
 
@@ -158,10 +157,7 @@ res_build_start(res_state x)
 
        res->retry = RES_DFLRETRY;
        res->options = RES_DEFAULT;
-       
-       rf = open("/dev/random", O_RDONLY, 0);
-       read(rf, &(res->id), 2);
-       close(rf);
+       res->id = res_randomid();
        
        res->ndots = 1;
        res->_vcsock = -1;
@@ -1367,33 +1363,15 @@ net_mask(in)            /* XXX - should really use system's version of this */
 #endif
 
 u_int
-res_randomid(void) {
-       struct timeval now;
+res_randomid(void)
+{
 #ifdef __APPLE__
-       int rf;
-       static u_int x = 0;
-
-       if (x == 0)
-       {
-               rf = open("/dev/random", O_RDONLY, 0);
-               if (rf >= 0)
-               {
-                       read(rf, &x, sizeof(u_int));
-                       close(rf);
-               }
-               else
-               {
-                       x = (getpid() << 10) + time(NULL);
-               }
-
-               srandom(x);
-       }
-
-       return random();
-#endif
-
+       return arc4random();
+#else
+       struct timeval now;
        gettimeofday(&now, NULL);
        return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
+#endif
 }
 
 /*
index e70c2e422f1c7bc1ae507128fae84165bdff075b..1018e6c247e05f2e0c2e1316b1ecb42254ab9e2d 100644 (file)
@@ -133,6 +133,11 @@ static const int highestFD = FD_SETSIZE - 1;
 
 #define MAX_HOOK_RETRIES 42
 
+/* port randomization */
+#define RANDOM_BIND_MAX_TRIES 16
+#define RANDOM_BIND_FIRST IPPORT_HIFIRSTAUTO
+#define RANDOM_BIND_LAST IPPORT_HILASTAUTO
+
 /* Forward. */
 
 static int             get_salen __P((const struct sockaddr *));
@@ -149,6 +154,29 @@ static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
 static int interrupt_pipe_enabled = 0;
 static pthread_key_t interrupt_pipe_key;
 
+static int
+bind_random(int sock)
+{
+       int i, status;
+       uint16_t src_port;
+       struct sockaddr_in local;
+
+       src_port = 0;
+       status = -1;
+
+       for (i = 0; (i < RANDOM_BIND_MAX_TRIES) && (status < 0); i++)
+       {               
+               /* random port in the range RANDOM_BIND_FIRST to RANDOM_BIND_LAST */
+               src_port = (res_randomid() % (RANDOM_BIND_LAST - RANDOM_BIND_FIRST)) + RANDOM_BIND_FIRST;
+               memset(&local, 0, sizeof(struct sockaddr_in));
+               local.sin_port = htons(src_port);
+
+               status = bind(sock, (struct sockaddr *)&local, sizeof(struct sockaddr_in));
+       }
+
+       return status;
+}
+
 void
 res_delete_interrupt_token(void *token)
 {
@@ -1155,6 +1183,8 @@ send_dg(res_state statp, const u_char *buf, int buflen, u_char *ans, int *anssiz
                        return DNS_RES_STATUS_SYSTEM_ERROR;
                }
 
+               bind_random(EXT(statp).nssocks[ns]);
+
 #ifndef CANNOT_CONNECT_DGRAM
                /*
                 * On a 4.3BSD+ machine (client and server,