Source-Changes-HG archive

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

[src/trunk]: src/external/apache2/mDNSResponder/dist Import mDNSResponder-320...



details:   https://anonhg.NetBSD.org/src/rev/f5f2700d6890
branches:  trunk
changeset: 795084:f5f2700d6890
user:      pettai <pettai%NetBSD.org@localhost>
date:      Mon Mar 31 23:26:30 2014 +0000

description:
Import mDNSResponder-320.16, merge, fix conflicts

diffstat:

 external/apache2/mDNSResponder/dist/Clients/dns-sd.c              |    70 +-
 external/apache2/mDNSResponder/dist/mDNSCore/DNSCommon.c          |   168 +-
 external/apache2/mDNSResponder/dist/mDNSCore/DNSDigest.c          |     2 +-
 external/apache2/mDNSResponder/dist/mDNSCore/mDNS.c               |  1958 ++++++++-
 external/apache2/mDNSResponder/dist/mDNSCore/mDNSEmbeddedAPI.h    |   223 +-
 external/apache2/mDNSResponder/dist/mDNSPosix/mDNSPosix.c         |    42 +-
 external/apache2/mDNSResponder/dist/mDNSShared/dns_sd.h           |    35 +-
 external/apache2/mDNSResponder/dist/mDNSShared/dnssd_clientstub.c |    69 +-
 external/apache2/mDNSResponder/dist/mDNSShared/dnssd_ipc.h        |     4 +-
 external/apache2/mDNSResponder/dist/mDNSShared/uds_daemon.c       |  1167 ++++-
 10 files changed, 3056 insertions(+), 682 deletions(-)

diffs (truncated from 6025 to 300 lines):

diff -r 67c03c3f6a12 -r f5f2700d6890 external/apache2/mDNSResponder/dist/Clients/dns-sd.c
--- a/external/apache2/mDNSResponder/dist/Clients/dns-sd.c      Mon Mar 31 23:21:21 2014 +0000
+++ b/external/apache2/mDNSResponder/dist/Clients/dns-sd.c      Mon Mar 31 23:26:30 2014 +0000
@@ -736,7 +736,12 @@
        if (errorCode)
                {
                if (errorCode == kDNSServiceErr_NoSuchRecord) printf("No Such Record");
-               else                                          printf("Error code %d", errorCode);
+               else if (errorCode == kDNSServiceErr_Timeout)
+                       {
+                       printf("No Such Record\n");
+                       printf("Query Timed Out\n");
+                       exit(1);
+                       }
                }
        printf("\n");
 
@@ -947,7 +952,7 @@
        if (addrs) freeaddrinfo(addrs);
        }
 
-static DNSServiceErrorType RegisterProxyAddressRecord(DNSServiceRef sdref, const char *host, const char *ip)
+static DNSServiceErrorType RegisterProxyAddressRecord(DNSServiceRef sdref, const char *host, const char *ip, DNSServiceFlags flags)
        {
        // Call getip() after the call DNSServiceCreateConnection().
        // On the Win32 platform, WinSock must be initialized for getip() to succeed.
@@ -955,11 +960,12 @@
        // DNSServiceCreateConnection() is called before getip() is.
        struct sockaddr_storage hostaddr;
        getip(ip, &hostaddr);
+       flags |= kDNSServiceFlagsUnique;
        if (hostaddr.ss_family == AF_INET)
-               return(DNSServiceRegisterRecord(sdref, &record, kDNSServiceFlagsUnique, opinterface, host,
+               return(DNSServiceRegisterRecord(sdref, &record, flags, opinterface, host,
                        kDNSServiceType_A,    kDNSServiceClass_IN,  4, &((struct sockaddr_in *)&hostaddr)->sin_addr,  240, MyRegisterRecordCallback, (void*)host));
        else if (hostaddr.ss_family == AF_INET6)
-               return(DNSServiceRegisterRecord(sdref, &record, kDNSServiceFlagsUnique, opinterface, host,
+               return(DNSServiceRegisterRecord(sdref, &record, flags, opinterface, host,
                        kDNSServiceType_AAAA, kDNSServiceClass_IN, 16, &((struct sockaddr_in6*)&hostaddr)->sin6_addr, 240, MyRegisterRecordCallback, (void*)host));
        else return(kDNSServiceErr_BadParam);
        }
@@ -971,9 +977,8 @@
 #define HexPair(P) ((HexVal((P)[0]) << 4) | HexVal((P)[1]))
 
 static DNSServiceErrorType RegisterService(DNSServiceRef *sdref,
-       const char *nam, const char *typ, const char *dom, const char *host, const char *port, int argc, char **argv)
+       const char *nam, const char *typ, const char *dom, const char *host, const char *port, int argc, char **argv, DNSServiceFlags flags)
        {
-       DNSServiceFlags flags = 0;
        uint16_t PortAsNumber = atoi(port);
        Opaque16 registerPort = { { PortAsNumber >> 8, PortAsNumber & 0xFF } };
        unsigned char txt[2048] = "";
@@ -1008,7 +1013,7 @@
        
        //flags |= kDNSServiceFlagsAllowRemoteQuery;
        //flags |= kDNSServiceFlagsNoAutoRename;
-       
+
        return(DNSServiceRegister(sdref, flags, opinterface, nam, typ, dom, host, registerPort.NotAnInteger, (uint16_t) (ptr-txt), txt, reg_reply, NULL));
        }
 
@@ -1025,6 +1030,7 @@
        DNSServiceErrorType err;
        char buffer[TypeBufferSize], *typ, *dom;
        int opi;
+       DNSServiceFlags flags = 0;
 
        // Extract the program name from argv[0], which by convention contains the path to this executable.
        // Note that this is just a voluntary convention, not enforced by the kernel --
@@ -1063,6 +1069,14 @@
                printf("Using P2P\n");
                }
 
+       if (argc > 1 && !strcasecmp(argv[1], "-includep2p"))
+               {
+               argc--;
+               argv++;
+               flags |= kDNSServiceFlagsIncludeP2P;
+               printf("Including P2P\n");
+               }
+
        if (argc > 2 && !strcmp(argv[1], "-i"))
                {
                opinterface = if_nametoindex(argv[2]);
@@ -1073,7 +1087,7 @@
                }
 
        if (argc < 2) goto Fail;        // Minimum command line is the command name and one argument
-       operation = getfirstoption(argc, argv, "EFBZLRPQqCAUNTMISV"
+       operation = getfirstoption(argc, argv, "EFBZLlRPQqtCAUNTMISV"
                                                                #if HAS_NAT_PMP_API
                                                                        "X"
                                                                #endif
@@ -1104,7 +1118,7 @@
                                        typ = gettype(buffer, typ);
                                        if (dom[0] == '.' && dom[1] == 0) dom[0] = 0;   // We allow '.' on the command line as a synonym for empty string
                                        printf("Browsing for %s%s%s\n", typ, dom[0] ? "." : "", dom);
-                                       err = DNSServiceBrowse(&client, 0, opinterface, typ, dom, browse_reply, NULL);
+                                       err = DNSServiceBrowse(&client, flags, opinterface, typ, dom, browse_reply, NULL);
                                        break;
 
                case 'Z':       typ = (argc < opi+1) ? "" : argv[opi+0];
@@ -1117,40 +1131,44 @@
                                        err = DNSServiceBrowse(&sc1, kDNSServiceFlagsShareConnection, opinterface, typ, dom, zonedata_browse, NULL);
                                        break;
 
-               case 'L':       if (argc < opi+2) goto Fail;
-                                       typ = (argc < opi+2) ? ""      : argv[opi+1];
-                                       dom = (argc < opi+3) ? "local" : argv[opi+2];
-                                       typ = gettype(buffer, typ);
-                                       if (dom[0] == '.' && dom[1] == 0) dom = "local";   // We allow '.' on the command line as a synonym for "local"
-                                       printf("Lookup %s.%s.%s\n", argv[opi+0], typ, dom);
-                                       err = DNSServiceResolve(&client, 0, opinterface, argv[opi+0], typ, dom, resolve_reply, NULL);
-                                       break;
+               case 'l':
+               case 'L':       {
+                                       DNSServiceFlags rflags = 0;
+                                       if (argc < opi+2) goto Fail;
+                                       typ = (argc < opi+2) ? ""      : argv[opi+1];
+                                       dom = (argc < opi+3) ? "local" : argv[opi+2];
+                                       typ = gettype(buffer, typ);
+                                       if (dom[0] == '.' && dom[1] == 0) dom = "local";   // We allow '.' on the command line as a synonym for "local"
+                                       printf("Lookup %s.%s.%s\n", argv[opi+0], typ, dom);
+                                       if (operation == 'l') rflags |= kDNSServiceFlagsWakeOnResolve;
+                                       err = DNSServiceResolve(&client, rflags, opinterface, argv[opi+0], typ, dom, resolve_reply, NULL);
+                                       break;
+                                       }
 
                case 'R':       if (argc < opi+4) goto Fail;
                                        typ = (argc < opi+2) ? "" : argv[opi+1];
                                        dom = (argc < opi+3) ? "" : argv[opi+2];
                                        typ = gettype(buffer, typ);
                                        if (dom[0] == '.' && dom[1] == 0) dom[0] = 0;   // We allow '.' on the command line as a synonym for empty string
-                                       err = RegisterService(&client, argv[opi+0], typ, dom, NULL, argv[opi+3], argc-(opi+4), argv+(opi+4));
+                                       err = RegisterService(&client, argv[opi+0], typ, dom, NULL, argv[opi+3], argc-(opi+4), argv+(opi+4), flags);
                                        break;
 
                case 'P':       if (argc < opi+6) goto Fail;
                                        err = DNSServiceCreateConnection(&client_pa);
                                        if (err) { fprintf(stderr, "DNSServiceCreateConnection returned %d\n", err); return(err); }
-                                       err = RegisterProxyAddressRecord(client_pa, argv[opi+4], argv[opi+5]);
-                                       //err = RegisterProxyAddressRecord(client_pa, "two", argv[opi+5]);
+                                       err = RegisterProxyAddressRecord(client_pa, argv[opi+4], argv[opi+5], flags);
                                        if (err) break;
-                                       err = RegisterService(&client, argv[opi+0], gettype(buffer, argv[opi+1]), argv[opi+2], argv[opi+4], argv[opi+3], argc-(opi+6), argv+(opi+6));
-                                       //DNSServiceRemoveRecord(client_pa, record, 0);
-                                       //DNSServiceRemoveRecord(client_pa, record, 0);
+                                       err = RegisterService(&client, argv[opi+0], gettype(buffer, argv[opi+1]), argv[opi+2], argv[opi+4], argv[opi+3], argc-(opi+6), argv+(opi+6), flags);
                                        break;
 
+               case 't':
                case 'q':
                case 'Q':
                case 'C':       {
                                        uint16_t rrtype, rrclass;
-                                       DNSServiceFlags flags = kDNSServiceFlagsReturnIntermediates;
+                                       flags |= kDNSServiceFlagsReturnIntermediates;
                                        if (operation == 'q') flags |= kDNSServiceFlagsSuppressUnusable;
+                                       if (operation == 't') flags |= (kDNSServiceFlagsSuppressUnusable | kDNSServiceFlagsTimeout);
                                        if (argc < opi+1) goto Fail;
                                        rrtype = (argc <= opi+1) ? kDNSServiceType_A  : GetRRType(argv[opi+1]);
                                        rrclass = (argc <= opi+2) ? kDNSServiceClass_IN : atoi(argv[opi+2]);
@@ -1186,8 +1204,8 @@
                                        static const char TXT1[] = "\xC" "First String"  "\xD" "Second String" "\xC" "Third String";
                                        static const char TXT2[] = "\xD" "Fourth String" "\xC" "Fifth String"  "\xC" "Sixth String";
                                        printf("Registering Service Test._testdualtxt._tcp.local.\n");
-                                       err = DNSServiceRegister(&client, 0, opinterface, "Test", "_testdualtxt._tcp.", "", NULL, registerPort.NotAnInteger, sizeof(TXT1)-1, TXT1, reg_reply, NULL);
-                                       if (!err) err = DNSServiceAddRecord(client, &record, 0, kDNSServiceType_TXT, sizeof(TXT2)-1, TXT2, 0);
+                                       err = DNSServiceRegister(&client, flags, opinterface, "Test", "_testdualtxt._tcp.", "", NULL, registerPort.NotAnInteger, sizeof(TXT1)-1, TXT1, reg_reply, NULL);
+                                       if (!err) err = DNSServiceAddRecord(client, &record, flags, kDNSServiceType_TXT, sizeof(TXT2)-1, TXT2, 0);
                                        break;
                                        }
 
diff -r 67c03c3f6a12 -r f5f2700d6890 external/apache2/mDNSResponder/dist/mDNSCore/DNSCommon.c
--- a/external/apache2/mDNSResponder/dist/mDNSCore/DNSCommon.c  Mon Mar 31 23:21:21 2014 +0000
+++ b/external/apache2/mDNSResponder/dist/mDNSCore/DNSCommon.c  Mon Mar 31 23:26:30 2014 +0000
@@ -989,8 +989,31 @@
 // Set up a AuthRecord with sensible default values.
 // These defaults may be overwritten with new values before mDNS_Register is called
 mDNSexport void mDNS_SetupResourceRecord(AuthRecord *rr, RData *RDataStorage, mDNSInterfaceID InterfaceID,
-       mDNSu16 rrtype, mDNSu32 ttl, mDNSu8 RecordType, mDNSRecordCallback Callback, void *Context)
+       mDNSu16 rrtype, mDNSu32 ttl, mDNSu8 RecordType, AuthRecType artype, mDNSRecordCallback Callback, void *Context)
        {
+       //
+       // LocalOnly auth record can be created with LocalOnly InterfaceID or a valid InterfaceID.
+       // Most of the applications normally create with LocalOnly InterfaceID and we store them as
+       // such, so that we can deliver the response to questions that specify LocalOnly InterfaceID.
+       // LocalOnly resource records can also be created with valid InterfaceID which happens today
+       // when we create LocalOnly records for /etc/hosts.
+
+       if (InterfaceID == mDNSInterface_LocalOnly && artype != AuthRecordLocalOnly)
+               {
+               LogMsg("mDNS_SetupResourceRecord: ERROR!! Mismatch LocalOnly record InterfaceID %p called with artype %d", InterfaceID, artype);
+               return;
+               }
+       else if (InterfaceID == mDNSInterface_P2P && artype != AuthRecordP2P)
+               {
+               LogMsg("mDNS_SetupResourceRecord: ERROR!! Mismatch P2P record InterfaceID %p called with artype %d", InterfaceID, artype);
+               return;
+               }
+       else if (!InterfaceID && (artype == AuthRecordP2P || artype == AuthRecordLocalOnly))
+               {
+               LogMsg("mDNS_SetupResourceRecord: ERROR!! Mismatch InterfaceAny record InterfaceID %p called with artype %d", InterfaceID, artype);
+               return;
+               }
+
        // Don't try to store a TTL bigger than we can represent in platform time units
        if (ttl > 0x7FFFFFFFUL / mDNSPlatformOneSecond)
                ttl = 0x7FFFFFFFUL / mDNSPlatformOneSecond;
@@ -1033,6 +1056,7 @@
        rr->AddressProxy      = zeroAddr;
        rr->TimeRcvd          = 0;
        rr->TimeExpire        = 0;
+       rr->ARType            = artype;
 
        // Field Group 3: Transient state for Authoritative Records (set in mDNS_Register_internal)
        // Field Group 4: Transient uDNS state for Authoritative Records (set in mDNS_Register_internal)
@@ -1074,6 +1098,12 @@
        q->ForceMCast          = mDNSfalse;
        q->ReturnIntermed      = mDNSfalse;
        q->SuppressUnusable    = mDNSfalse;
+       q->SearchListIndex     = 0;
+       q->AppendSearchDomains = 0;
+       q->RetryWithSearchDomains = mDNSfalse;
+       q->TimeoutQuestion     = 0;
+       q->WakeOnResolve       = 0;
+       q->qnameOrig           = mDNSNULL;
        q->QuestionCallback    = callback;
        q->QuestionContext     = context;
        }
@@ -1186,6 +1216,13 @@
 
 mDNSexport mDNSBool SameNameRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q)
        {
+       // LocalOnly/P2P questions can be answered with AuthRecordAny in this function. LocalOnly/P2P records
+       // are handled in LocalOnlyRecordAnswersQuestion
+       if ((rr->InterfaceID == mDNSInterface_LocalOnly) || (rr->InterfaceID == mDNSInterface_P2P))
+               {
+               LogMsg("SameNameRecordAnswersQuestion: ERROR!! called with LocalOnly ResourceRecord %p, Question %p", rr->InterfaceID, q->InterfaceID);
+               return mDNSfalse;
+               }
        if (rr->InterfaceID &&
                q ->InterfaceID && q->InterfaceID != mDNSInterface_LocalOnly &&
                rr->InterfaceID != q->InterfaceID) return(mDNSfalse);
@@ -1205,6 +1242,14 @@
 
 mDNSexport mDNSBool ResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q)
        {
+       // LocalOnly/P2P questions can be answered with AuthRecordAny in this function. LocalOnly/P2P records
+       // are handled in LocalOnlyRecordAnswersQuestion
+       if ((rr->InterfaceID == mDNSInterface_LocalOnly) || (rr->InterfaceID == mDNSInterface_P2P))
+               {
+               LogMsg("ResourceRecordAnswersQuestion: ERROR!! called with LocalOnly/P2P ResourceRecord %p, Question %p", rr->InterfaceID, q->InterfaceID);
+               return mDNSfalse;
+               }
+
        if (rr->InterfaceID &&
                q ->InterfaceID && q->InterfaceID != mDNSInterface_LocalOnly &&
                rr->InterfaceID != q->InterfaceID) return(mDNSfalse);
@@ -1213,10 +1258,6 @@
        if (!rr->InterfaceID && rr->rDNSServer != q->qDNSServer) return(mDNSfalse);
 
        // If ResourceRecord received via multicast, but question was unicast, then shouldn't use record to answer this question.
-       // This also covers the case where the ResourceRecord is mDNSInterface_LocalOnly and the question is expecting a unicast
-       // DNS response. We don't want a local process to be able to create a fake LocalOnly address record for "www.bigbank.com"
-       // which would then cause other applications (e.g. Safari) to connect to the wrong address. If we decide to support this later,
-       // the restrictions need to be at least as strict as the restrictions on who can edit /etc/hosts and put fake addresses there.
        if (rr->InterfaceID && !mDNSOpaque16IsZero(q->TargetQID)) return(mDNSfalse);
 
        // RR type CNAME matches any query type. QTYPE ANY matches any RR type. QCLASS ANY matches any RR class.
@@ -1226,8 +1267,91 @@
        return(rr->namehash == q->qnamehash && SameDomainName(rr->name, &q->qname));
        }
 
+// We have a separate function to handle LocalOnly AuthRecords because they can be created with
+// a valid InterfaceID (e.g., scoped /etc/hosts) and can be used to answer unicast questions unlike
+// multicast resource records (which has a valid InterfaceID) which can't be used to answer
+// unicast questions. ResourceRecordAnswersQuestion/SameNameRecordAnswersQuestion can't tell whether
+// a resource record is multicast or LocalOnly by just looking at the ResourceRecord because
+// LocalOnly records are truly identified by ARType in the AuthRecord.  As P2P and LocalOnly record
+// are kept in the same hash table, we use the same function to make it easy for the callers when
+// they walk the hash table to answer LocalOnly/P2P questions
+//
+mDNSexport mDNSBool LocalOnlyRecordAnswersQuestion(AuthRecord *const ar, const DNSQuestion *const q)
+       {
+       ResourceRecord *rr = &ar->resrec;
+       
+       // mDNSInterface_Any questions can be answered with LocalOnly/P2P records in this function. AuthRecord_Any
+       // records are handled in ResourceRecordAnswersQuestion/SameNameRecordAnswersQuestion
+       if (RRAny(ar))
+               {
+               LogMsg("LocalOnlyRecordAnswersQuestion: ERROR!! called with regular AuthRecordAny %##s", rr->name->c);
+               return mDNSfalse;
+               }
+               
+       // Questions with mDNSInterface_LocalOnly InterfaceID should be answered with all resource records that are
+       // *local* to the machine. These include resource records that have InterfaceID set to mDNSInterface_LocalOnly,
+       // mDNSInterface_Any and any other real InterfaceID. Hence, LocalOnly questions should not be checked against
+       // the InterfaceID in the resource record.
+       //



Home | Main Index | Thread Index | Old Index