Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/apache2/mDNSResponder/nss For the multicast_dns onl...



details:   https://anonhg.NetBSD.org/src/rev/b88711800e3f
branches:  trunk
changeset: 748504:b88711800e3f
user:      tsarna <tsarna%NetBSD.org@localhost>
date:      Mon Oct 26 00:46:19 2009 +0000

description:
For the multicast_dns only mode, be very restrictive in what lookups we
try. No point in making queries and waiting for timeouts on lookups that
will never succeed.

Now only does lookups for linklocal addresses (v4 or v6) and
"name.local" names (and dotless names, iff "local" is specified in the
resolv.conf search list).

Also, lower the timeout in this mode, since multicast lookups should
return pretty fast or not at all.

diffstat:

 external/apache2/mDNSResponder/nss/nss_mdnsd.c |  218 ++++++++++++++++--------
 1 files changed, 147 insertions(+), 71 deletions(-)

diffs (truncated from 389 to 300 lines):

diff -r 517024be8bdc -r b88711800e3f external/apache2/mDNSResponder/nss/nss_mdnsd.c
--- a/external/apache2/mDNSResponder/nss/nss_mdnsd.c    Mon Oct 26 00:24:20 2009 +0000
+++ b/external/apache2/mDNSResponder/nss/nss_mdnsd.c    Mon Oct 26 00:46:19 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nss_mdnsd.c,v 1.1 2009/10/25 00:17:06 tsarna Exp $     */
+/*     $NetBSD: nss_mdnsd.c,v 1.2 2009/10/26 00:46:19 tsarna Exp $     */
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -85,14 +85,9 @@
 
 #define HCTX_BUFLEFT(c) (sizeof((c)->buf) - ((c)->next - (c)->buf))
 
-typedef struct search_domain {
-    const char *name;
-    bool        enabled;
-} search_domain;
-
 typedef struct search_iter {
     const char     *name;
-    search_domain  *next_search;
+    char           **next_search;
     size_t          baselen;
     bool            abs_first;
     bool            abs_last;
@@ -102,7 +97,7 @@
 static hostent_ctx h_ctx;
 static DNSServiceFlags svc_flags = 0;
 static int ndots = 1, timeout = 1000;
-static search_domain *search_domains, *no_search;
+static char **search_domains, **no_search;
 
 ns_mtab *nss_module_register(const char *, u_int *, nss_module_unregister_fn *);
 static int load_config(res_state);
@@ -136,6 +131,7 @@
 
 void search_init(search_iter *, const char *);
 const char *search_next(search_iter *);
+bool searchable_domain(char *);
 
 
 
@@ -153,8 +149,6 @@
 {
     res_state res;
 
-    UNUSED(unreg);
-    
     *nelems = sizeof(mtab) / sizeof(mtab[0]);
     *unreg = NULL;
 
@@ -179,16 +173,27 @@
     int count = 0;
     char **sd;
     
-    ndots = res->ndots;
-    timeout = res->retrans * 1000; /* retrans in sec to timeout in msec */
+    /* free old search list, if any */
 
+    if ((no_search = search_domains)) {
+        for (; *no_search; no_search++) {
+            free(*no_search);
+        }
+        
+        free(search_domains);
+    }
+
+    /* new search list */
+    
     sd = res->dnsrch;
     while (*sd) {
-        count++;
+        if (searchable_domain(*sd)) {
+            count++;
+        }
         sd++;
     }
     
-    search_domains = malloc(sizeof(search_domain) * (count + 1));
+    search_domains = calloc(sizeof(char *), count + 1);
     if (!search_domains) {
         return -1;
     }
@@ -196,15 +201,24 @@
     sd = res->dnsrch;
     no_search = search_domains;
     while (*sd) {
-        no_search->name = *sd;
-        no_search->enabled =
-            (svc_flags & kDNSServiceFlagsForceMulticast) ? true : true;
-        no_search++;
+        if (searchable_domain(*sd)) {
+            *no_search = strdup(*sd);
+            no_search++;
+        }
         sd++;
     }
 
-    /* terminate list */
-    no_search->name = NULL;
+    /* retrans in sec to timeout in msec */
+    timeout = res->retrans * 1000;
+
+    if (svc_flags & kDNSServiceFlagsForceMulticast) {
+        ndots = 1;
+        if (timeout > 2000) {
+            timeout = 2000;
+        }
+    } else {
+        ndots = res->ndots;
+    }
 }
 
 
@@ -243,6 +257,14 @@
         return NS_UNAVAIL;
     }
 
+    search_init(&iter, name);
+    sname = search_next(&iter);
+
+    if (!sname) {
+        h_errno = HOST_NOT_FOUND;
+        return NS_NOTFOUND;
+    }
+
     /* use one connection for all searches */
     if (DNSServiceCreateConnection(&sdRef)) {
         h_errno = NETDB_INTERNAL;
@@ -250,9 +272,7 @@
     }
     
     _mdns_addrinfo_init(&ctx, pai);
-    search_init(&iter, name);
-    sname = search_next(&iter);
-    
+
     while (sname && (err != NS_SUCCESS)) {
         err = _mdns_getaddrinfo_abs(sname, proto, sdRef, &ctx);
         if (err != NS_SUCCESS) {
@@ -279,7 +299,7 @@
 
     err = DNSServiceGetAddrInfo(
         &sdRef,
-        svc_flags,
+        svc_flags | kDNSServiceFlagsReturnIntermediates,
         kDNSServiceInterfaceIndexAny,
         proto,
         name,
@@ -291,7 +311,6 @@
         h_errno = NETDB_INTERNAL;
         return NS_UNAVAIL;
     }
-    
     _mdns_eventloop(sdRef, (void *)ctx);
 
     DNSServiceRefDeallocate(sdRef);
@@ -324,12 +343,28 @@
 
     switch (af) {
     case AF_INET:
+        /* if mcast-only don't bother for non-LinkLocal addrs) */
+        if (svc_flags & kDNSServiceFlagsForceMulticast) {
+            if ((addr[0] != 169) || (addr[1] != 254)) {
+                h_errno = HOST_NOT_FOUND;
+                return NS_NOTFOUND;
+            }
+        }
+
         (void)snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u.in-addr.arpa",
             (addr[3] & 0xff), (addr[2] & 0xff),
             (addr[1] & 0xff), (addr[0] & 0xff));
         break;
     
     case AF_INET6:
+        /* if mcast-only don't bother for non-LinkLocal addrs) */
+        if (svc_flags & kDNSServiceFlagsForceMulticast) {
+            if ((addr[0] != 0xfe) || ((addr[1] & 0xc0) != 0x80)) {
+                h_errno = HOST_NOT_FOUND;
+                return NS_NOTFOUND;
+            }
+        }
+        
         qp = qbuf;
         ep = qbuf + sizeof(qbuf) - 1;
         for (n = IN6ADDRSZ - 1; n >= 0; n--) {
@@ -417,7 +452,15 @@
         break;
 
     default:
-        h_errno = NETDB_INTERNAL;
+        h_errno = NO_RECOVERY;
+        return NS_UNAVAIL;
+    }
+
+    search_init(&iter, name);
+    sname = search_next(&iter);
+
+    if (!sname) {
+        h_errno = HOST_NOT_FOUND;
         return NS_NOTFOUND;
     }
 
@@ -428,9 +471,7 @@
     }
     
     _mdns_hostent_init(&h_ctx, af, addrlen);
-    search_init(&iter, name);
-    sname = search_next(&iter);
-    
+
     while (sname && (err != NS_SUCCESS)) {
         err = _mdns_gethtbyname_abs(sname, rrtype, sdRef);
         if (err != NS_SUCCESS) {
@@ -458,7 +499,7 @@
 
     err = DNSServiceQueryRecord(
         &sdRef,
-        svc_flags,
+        svc_flags | kDNSServiceFlagsReturnIntermediates,
         kDNSServiceInterfaceIndexAny,
         name,
         rrtype,
@@ -642,7 +683,6 @@
 
     UNUSED(sdRef);
     UNUSED(interfaceIndex);
-    UNUSED(hostname);
     UNUSED(ttl);
 
     if (errorCode == kDNSServiceErr_NoError) {
@@ -723,6 +763,8 @@
             }
             break;
         }
+    } else if (errorCode == kDNSServiceErr_NoSuchRecord) {
+        ctx->cb_ctx.done = true;
     }
 }
 
@@ -820,35 +862,52 @@
 void
 search_init(search_iter *iter, const char *name)
 {
-    const char *c = name;
-    bool enddot = false;
-    int dots = 0;
+    const char *c = name, *cmp;
+    int dots = 0, enddot = 0;
+    size_t len, cl;
 
     iter->name = name;
     iter->baselen = 0;
+    iter->abs_first = iter->abs_last = false;
+    iter->next_search = search_domains;
         
     while (*c) {
         if (*c == '.') {
             dots++;
-            enddot = true;
+            enddot = 1;
         } else {
-            enddot = false;
+            enddot = 0;
         }
         c++;
     } 
     
-    if (dots >= ndots) {
-        iter->abs_first = true;
-        iter->abs_last = false;
+    if (svc_flags & kDNSServiceFlagsForceMulticast) {
+        if (dots) {
+            iter->next_search = no_search;
+            if ((dots - enddot) == 1) {
+                len = strlen(iter->name);
+                cl = strlen(".local") + enddot;
+                if (len > cl) {
+                    cmp = enddot ? ".local." : ".local";
+                    c = iter->name + len - cl;
+                    
+                    if (!strcasecmp(c, cmp)) {
+                        iter->abs_first = true;
+                    }
+                }
+            }
+        }
     } else {
-        iter->abs_first = false;
-        iter->abs_last = true;
-    }
+        if (dots >= ndots) {
+            iter->abs_first = true;
+        } else {
+            iter->abs_last = true;
+        }
     
-    if (enddot) {
-        iter->next_search = no_search;
-    } else {



Home | Main Index | Thread Index | Old Index