]> git.saurik.com Git - apple/mdnsresponder.git/commitdiff
mDNSResponder-171.4.tar.gz mac-os-x-1053 mac-os-x-1054 v171.4
authorApple <opensource@apple.com>
Fri, 18 Apr 2008 20:33:56 +0000 (20:33 +0000)
committerApple <opensource@apple.com>
Fri, 18 Apr 2008 20:33:56 +0000 (20:33 +0000)
20 files changed:
Clients/dns-sd.c
Makefile
mDNSCore/DNSCommon.c
mDNSCore/DNSCommon.h
mDNSCore/mDNS.c
mDNSCore/mDNSDebug.h
mDNSCore/mDNSEmbeddedAPI.h
mDNSCore/uDNS.c
mDNSMacOSX/LaunchDaemonInfo.helper.plist
mDNSMacOSX/LaunchDaemonInfo.plist
mDNSMacOSX/daemon.c
mDNSMacOSX/helper.c
mDNSMacOSX/mDNSMacOSX.c
mDNSMacOSX/mDNSResponder.sb
mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj
mDNSShared/PlatformCommon.c
mDNSShared/dns_sd.h
mDNSShared/dnsextd.c
mDNSShared/dnssd_clientstub.c
mDNSShared/uds_daemon.c

index e80ee39af09becf357e80b84f6a736dece4e2efe..497c5dc269cb964ea53421b73b22b53805b854b0 100644 (file)
@@ -574,16 +574,16 @@ static void DNSSD_API port_mapping_create_reply(DNSServiceRef sdref, DNSServiceF
        (void)context;     // Unused
        (void)flags;       // Unused
        
-       if (num_printed++ == 0) printf("Timestamp     if   %-20s %-15s %-15s %-15s %s\n", "External Address", "Protocol", "Internal Port", "External Port", "TTL");
+       if (num_printed++ == 0) printf("Timestamp     if   %-20s %-15s %-15s %-15s %-6s\n", "External Address", "Protocol", "Internal Port", "External Port", "TTL");
        printtimestamp();
-       if (errorCode) printf("Error code %d\n", errorCode);
+       if (errorCode && errorCode != kDNSServiceErr_DoubleNAT) printf("Error code %d\n", errorCode);
        else
                {
                const unsigned char *digits = (const unsigned char *)&publicAddress;
                char                 addr[256];
 
                snprintf(addr, sizeof(addr), "%d.%d.%d.%d", digits[0], digits[1], digits[2], digits[3]);
-               printf("%-4d %-20s %-15d %-15d %-15d %d\n", ifIndex, addr, protocol, ntohs(privatePort), ntohs(publicPort), ttl);
+               printf("%-4d %-20s %-15d %-15d %-15d %-6d%s\n", ifIndex, addr, protocol, ntohs(privatePort), ntohs(publicPort), ttl, errorCode == kDNSServiceErr_DoubleNAT ? " Double NAT" : "");
                }
        fflush(stdout);
        }
@@ -597,23 +597,27 @@ static void DNSSD_API addrinfo_reply(DNSServiceRef sdref, DNSServiceFlags flags,
        (void) sdref;
        (void) context;
        
-       if (num_printed++ == 0) printf("Timestamp     A/R Flags if %-25s %-40s %s\n", "Hostname", "Address", "TTL");
+       if (num_printed++ == 0) printf("Timestamp     A/R Flags if %-25s %-44s %s\n", "Hostname", "Address", "TTL");
        printtimestamp();
 
        if (address && address->sa_family == AF_INET)
                {
-               const unsigned char *digits = (const unsigned char *) &((struct sockaddr_in *)address)->sin_addr;
-               snprintf(addr, sizeof(addr), "%d.%d.%d.%d", digits[0], digits[1], digits[2], digits[3]);
+               const unsigned char *b = (const unsigned char *) &((struct sockaddr_in *)address)->sin_addr;
+               snprintf(addr, sizeof(addr), "%d.%d.%d.%d", b[0], b[1], b[2], b[3]);
                }
        else if (address && address->sa_family == AF_INET6)
                {
-               const unsigned char *digits = (const unsigned char *) &((struct sockaddr_in6 *)address)->sin6_addr;
-               snprintf(addr, sizeof(addr), "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X",
-                               digits[0x0], digits[0x1], digits[0x2], digits[0x3], digits[0x4], digits[0x5], digits[0x6], digits[0x7],
-                               digits[0x8], digits[0x9], digits[0xA], digits[0xB], digits[0xC], digits[0xD], digits[0xE], digits[0xF]);
+               char if_name[IFNAMSIZ];         // Older Linux distributions don't define IF_NAMESIZE
+               const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *)address;
+               const unsigned char       *b  = (const unsigned char *      )&s6->sin6_addr;
+               if (!if_indextoname(s6->sin6_scope_id, if_name))
+                       snprintf(if_name, sizeof(if_name), "<%d>", s6->sin6_scope_id);
+               snprintf(addr, sizeof(addr), "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X%%%s",
+                               b[0x0], b[0x1], b[0x2], b[0x3], b[0x4], b[0x5], b[0x6], b[0x7],
+                               b[0x8], b[0x9], b[0xA], b[0xB], b[0xC], b[0xD], b[0xE], b[0xF], if_name);
                }
 
-       printf("%s%6X%3d %-25s %-40s %d", op, flags, interfaceIndex, hostname, addr, ttl);
+       printf("%s%6X%3d %-25s %-44s %d", op, flags, interfaceIndex, hostname, addr, ttl);
        if (errorCode)
                {
                if (errorCode == kDNSServiceErr_NoSuchRecord) printf("   No Such Record");
index c6aca02a526ce843f0808bcf97e6a6b384cc2bf7..ef3c0ee4a993a5ef5eff344a27c4f4902e7ac395 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@
 
 include /Developer/Makefiles/pb_makefiles/platform.make
 
-MVERS = "mDNSResponder-170"
+MVERS = "mDNSResponder-171.4"
 
 DDNSWRITECONFIG = "$(DSTROOT)/Library/Application Support/Bonjour/ddnswriteconfig"
 
index 7c17df69ee424ec16ae322704b4c4e270db58e0a..bffef7b13e64dfe67d13c9668b5451dd9b7360e1 100644 (file)
     Change History (most recent first):
 
 $Log: DNSCommon.c,v $
+Revision 1.199  2008/03/14 19:58:38  mcguire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+Make sure we add the record when sending LLQ refreshes
+
+Revision 1.198  2008/03/07 23:29:24  cheshire
+Fixed cosmetic byte order display issue in DumpPacket output
+
+Revision 1.197  2008/03/05 22:51:29  mcguire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+Even further refinements
+
+Revision 1.196  2008/03/05 22:01:53  cheshire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+Now that we optionally add the HINFO record, when rewriting the header fields into network byte
+order, we need to use our updated msg->h.numAdditionals, not the stack variable numAdditionals
+
+Revision 1.195  2008/03/05 19:06:30  mcguire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+further refinements
+
+Revision 1.194  2008/03/05 00:26:06  cheshire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+
 Revision 1.193  2007/12/17 23:42:36  cheshire
 Added comments about DNSDigest_SignMessage()
 
@@ -527,7 +550,7 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *rr, RDataBody *rd,
                                                                rd->soa.serial, rd->soa.refresh, rd->soa.retry, rd->soa.expire, rd->soa.min);
                                                        break;
 
-               case kDNSType_HINFO:// Display this the same as TXT (show all constituent string)
+               case kDNSType_HINFO:// Display this the same as TXT (show all constituent strings)
                case kDNSType_TXT:  {
                                                        mDNSu8 *t = rd->txt.c;
                                                        while (t < rd->txt.c + rr->rdlength)
@@ -2013,6 +2036,30 @@ mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease)
        return end;
        }
 
+mDNSexport mDNSu8 *putHINFO(const mDNS *const m, DNSMessage *const msg, mDNSu8 *end, DomainAuthInfo *authInfo)
+       {
+       if (authInfo && authInfo->AutoTunnel)
+               {
+               AuthRecord hinfo;
+               mDNSu8 *h = hinfo.rdatastorage.u.data;
+               mDNSu16 len = 2 + m->HIHardware.c[0] + m->HISoftware.c[0];
+               mDNSu8 *newptr;
+               mDNS_SetupResourceRecord(&hinfo, mDNSNULL, mDNSInterface_Any, kDNSType_HINFO, 0, kDNSRecordTypeUnique, mDNSNULL, mDNSNULL);
+               AppendDomainLabel(&hinfo.namestorage, &m->hostlabel);
+               AppendDomainName (&hinfo.namestorage, &authInfo->domain);
+               hinfo.resrec.rroriginalttl = 0;
+               mDNSPlatformMemCopy(h, &m->HIHardware, 1 + (mDNSu32)m->HIHardware.c[0]);
+               h += 1 + (int)h[0];
+               mDNSPlatformMemCopy(h, &m->HISoftware, 1 + (mDNSu32)m->HISoftware.c[0]);
+               hinfo.resrec.rdlength   = len;
+               hinfo.resrec.rdestimate = len;
+               newptr = PutResourceRecord(msg, end, &msg->h.numAdditionals, &hinfo.resrec);
+               return newptr;
+               }
+       else
+               return end;
+       }
+
 // ***************************************************************************
 #if COMPILER_LIKES_PRAGMA_MARK
 #pragma mark -
@@ -2531,10 +2578,11 @@ mDNSexport mStatus mDNSSendDNSMessage(mDNS *const m, DNSMessage *const msg, mDNS
     mDNSInterfaceID InterfaceID, const mDNSAddr *dst, mDNSIPPort dstport, TCPSocket *sock, DomainAuthInfo *authInfo)
        {
        mStatus status = mStatus_NoError;
-       mDNSu16 numQuestions   = msg->h.numQuestions;
-       mDNSu16 numAnswers     = msg->h.numAnswers;
-       mDNSu16 numAuthorities = msg->h.numAuthorities;
-       mDNSu16 numAdditionals = msg->h.numAdditionals;
+       const mDNSu16 numQuestions   = msg->h.numQuestions;
+       const mDNSu16 numAnswers     = msg->h.numAnswers;
+       const mDNSu16 numAuthorities = msg->h.numAuthorities;
+       const mDNSu16 numAdditionals = msg->h.numAdditionals;
+       mDNSu16 tmpNumAdditionals = numAdditionals;
        mDNSu8 *ptr = (mDNSu8 *)&msg->h.numQuestions;
 
        if (end <= msg->data || end - msg->data > AbsoluteMaxDNSMessageData)
@@ -2543,33 +2591,40 @@ mDNSexport mStatus mDNSSendDNSMessage(mDNS *const m, DNSMessage *const msg, mDNS
                return mStatus_BadParamErr;
                }
 
-       // Put all the integer values in IETF byte-order (MSB first, LSB second)
-       *ptr++ = (mDNSu8)(numQuestions   >> 8);
-       *ptr++ = (mDNSu8)(numQuestions   &  0xFF);
-       *ptr++ = (mDNSu8)(numAnswers     >> 8);
-       *ptr++ = (mDNSu8)(numAnswers     &  0xFF);
-       *ptr++ = (mDNSu8)(numAuthorities >> 8);
-       *ptr++ = (mDNSu8)(numAuthorities &  0xFF);
-       *ptr++ = (mDNSu8)(numAdditionals >> 8);
-       *ptr++ = (mDNSu8)(numAdditionals &  0xFF);
-
-       if (authInfo) DNSDigest_SignMessage(msg, &end, authInfo, 0);    // DNSDigest_SignMessage operates on message in network byte order
-       if (!end) { LogMsg("mDNSSendDNSMessage: DNSDigest_SignMessage failed"); status = mStatus_NoMemoryErr; }
+       end = putHINFO(m, msg, end, authInfo);
+       if (!end) { LogMsg("mDNSSendDNSMessage: putHINFO failed"); status = mStatus_NoMemoryErr; }
        else
                {
-               // Send the packet on the wire
-               if (!sock)
-                       status = mDNSPlatformSendUDP(m, msg, end, InterfaceID, dst, dstport);
+               tmpNumAdditionals = msg->h.numAdditionals;
+       
+               // Put all the integer values in IETF byte-order (MSB first, LSB second)
+               *ptr++ = (mDNSu8)(numQuestions   >> 8);
+               *ptr++ = (mDNSu8)(numQuestions   &  0xFF);
+               *ptr++ = (mDNSu8)(numAnswers     >> 8);
+               *ptr++ = (mDNSu8)(numAnswers     &  0xFF);
+               *ptr++ = (mDNSu8)(numAuthorities >> 8);
+               *ptr++ = (mDNSu8)(numAuthorities &  0xFF);
+               *ptr++ = (mDNSu8)(tmpNumAdditionals >> 8);
+               *ptr++ = (mDNSu8)(tmpNumAdditionals &  0xFF);
+       
+               if (authInfo) DNSDigest_SignMessage(msg, &end, authInfo, 0);    // DNSDigest_SignMessage operates on message in network byte order
+               if (!end) { LogMsg("mDNSSendDNSMessage: DNSDigest_SignMessage failed"); status = mStatus_NoMemoryErr; }
                else
                        {
-                       mDNSu16 msglen = (mDNSu16)(end - (mDNSu8 *)msg);
-                       mDNSu8 lenbuf[2] = { (mDNSu8)(msglen >> 8), (mDNSu8)(msglen & 0xFF) };
-                       long nsent = mDNSPlatformWriteTCP(sock, (char*)lenbuf, 2);              // Should do scatter/gather here -- this is probably going out as two packets
-                       if (nsent != 2) { LogMsg("mDNSSendDNSMessage: write msg length failed %d/%d", nsent, 2); status = mStatus_ConnFailed; }
+                       // Send the packet on the wire
+                       if (!sock)
+                               status = mDNSPlatformSendUDP(m, msg, end, InterfaceID, dst, dstport);
                        else
                                {
-                               nsent = mDNSPlatformWriteTCP(sock, (char *)msg, msglen);
-                               if (nsent != msglen) { LogMsg("mDNSSendDNSMessage: write msg body failed %d/%d", nsent, msglen); status = mStatus_ConnFailed; }
+                               mDNSu16 msglen = (mDNSu16)(end - (mDNSu8 *)msg);
+                               mDNSu8 lenbuf[2] = { (mDNSu8)(msglen >> 8), (mDNSu8)(msglen & 0xFF) };
+                               long nsent = mDNSPlatformWriteTCP(sock, (char*)lenbuf, 2);              // Should do scatter/gather here -- this is probably going out as two packets
+                               if (nsent != 2) { LogMsg("mDNSSendDNSMessage: write msg length failed %d/%d", nsent, 2); status = mStatus_ConnFailed; }
+                               else
+                                       {
+                                       nsent = mDNSPlatformWriteTCP(sock, (char *)msg, msglen);
+                                       if (nsent != msglen) { LogMsg("mDNSSendDNSMessage: write msg body failed %d/%d", nsent, msglen); status = mStatus_ConnFailed; }
+                                       }
                                }
                        }
                }
@@ -2578,15 +2633,18 @@ mDNSexport mStatus mDNSSendDNSMessage(mDNS *const m, DNSMessage *const msg, mDNS
        msg->h.numQuestions   = numQuestions;
        msg->h.numAnswers     = numAnswers;
        msg->h.numAuthorities = numAuthorities;
-       msg->h.numAdditionals = numAdditionals;
 
+       // Dump the packet with the HINFO and TSIG
        if (mDNS_LogLevel >= MDNS_LOG_VERBOSE_DEBUG && !mDNSOpaque16IsZero(msg->h.id))
                {
-               if (authInfo) msg->h.numAdditionals++;  // Want to include TSIG in DumpPacket output
+               ptr = (mDNSu8 *)&msg->h.numAdditionals;
+               msg->h.numAdditionals = (mDNSu16)ptr[0] << 8 | (mDNSu16)ptr[1];
                DumpPacket(m, mDNStrue, sock && (sock->flags & kTCPSocketFlags_UseTLS) ? "TLS" : sock ? "TCP" : "UDP", dst, dstport, msg, end);
-               if (authInfo) msg->h.numAdditionals--;
                }
 
+       // put the final integer value back the way it was
+       msg->h.numAdditionals = numAdditionals;
+
        return(status);
        }
 
index f186ac69aac33f5a4fb3c10055199e2f3b4fac42..655603104d275336cc38a0c4dfcccef015471f59 100644 (file)
     Change History (most recent first):
 
 $Log: DNSCommon.h,v $
+Revision 1.59  2008/03/14 19:58:38  mcguire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+Make sure we add the record when sending LLQ refreshes
+
+Revision 1.58  2008/03/06 21:26:10  cheshire
+Moved duplicated STRINGIFY macro from individual C files to DNSCommon.h
+
 Revision 1.57  2007/12/13 20:20:17  cheshire
 Minor efficiency tweaks -- converted IdenticalResourceRecord, IdenticalSameNameRecord, and
 SameRData from functions to macros, which allows the code to be inlined (the compiler can't
@@ -111,6 +118,15 @@ Split out SameRDataBody() into a separate routine so it can be called from other
        extern "C" {
 #endif
 
+//*************************************************************************************************************
+// Macros
+
+// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
+// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
+// To expand "version" to its value before making the string, use STRINGIFY(version) instead
+#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) #s
+#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
+
 // ***************************************************************************
 #if COMPILER_LIKES_PRAGMA_MARK
 #pragma mark - DNS Protocol Constants
@@ -278,6 +294,8 @@ extern mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domainname
 extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease);
 #define PutResourceRecord(MSG, P, C, RR) PutResourceRecordTTL((MSG), (P), (C), (RR), (RR)->rroriginalttl)
 
+extern mDNSu8 *putHINFO(const mDNS *const m, DNSMessage *const msg, mDNSu8 *end, DomainAuthInfo *authInfo);
+
 // ***************************************************************************
 #if COMPILER_LIKES_PRAGMA_MARK
 #pragma mark -
index 2d4f110d518bfcb598bc5517f16112eb4230a29c..34a3c7c915b83a43c5216b92a42d1237eb362e20 100755 (executable)
     Change History (most recent first):
 
 $Log: mDNS.c,v $
+Revision 1.776  2008/04/17 20:14:14  cheshire
+<rdar://problem/5870023> CurrentAnswers/LargeAnswers/UniqueAnswers counter mismatch
+
+Revision 1.775  2008/03/26 01:53:34  mcguire
+<rdar://problem/5820489> Can't resolve via uDNS when an interface is specified
+
+Revision 1.774  2008/03/17 17:46:08  mcguire
+When activating an LLQ, reset all the important state and destroy any tcp connection,
+so that everything will be restarted as if the question had just been asked.
+Also reset servPort, so that the SOA query will be re-issued.
+
+Revision 1.773  2008/03/14 22:52:36  mcguire
+<rdar://problem/5321824> write status to the DS
+Update status when any unicast LLQ is started
+
+Revision 1.772  2008/03/06 02:48:34  mcguire
+<rdar://problem/5321824> write status to the DS
+
+Revision 1.771  2008/02/26 22:04:44  cheshire
+<rdar://problem/5661661> BTMM: Too many members.mac.com SOA queries
+Additional fixes -- should not be calling uDNS_CheckCurrentQuestion on a
+question while it's still in our 'm->NewQuestions' section of the list
+
+Revision 1.770  2008/02/22 23:09:02  cheshire
+<rdar://problem/5338420> BTMM: Not processing additional records
+Refinements:
+1. Check rdatahash == namehash, to skip expensive SameDomainName check when possible
+2. Once we decide a record is acceptable, we can break out of the loop
+
+Revision 1.769  2008/02/22 00:00:19  cheshire
+<rdar://problem/5338420> BTMM: Not processing additional records
+
+Revision 1.768  2008/02/19 23:26:50  cheshire
+<rdar://problem/5661661> BTMM: Too many members.mac.com SOA queries
+
 Revision 1.767  2007/12/22 02:25:29  cheshire
 <rdar://problem/5661128> Records and Services sometimes not re-registering on wake from sleep
 
@@ -2444,7 +2479,7 @@ mDNSlocal void SendQueries(mDNS *const m)
                if (m->CurrentQuestion)
                        LogMsg("SendQueries ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
                m->CurrentQuestion = m->Questions;
-               while (m->CurrentQuestion)
+               while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
                        {
                        q = m->CurrentQuestion;
                        if (ActiveQuestion(q) && !mDNSOpaque16IsZero(q->TargetQID)) uDNS_CheckCurrentQuestion(m);
@@ -2476,6 +2511,7 @@ mDNSlocal void SendQueries(mDNS *const m)
                        // m->CurrentQuestion point to the right question
                        if (q == m->CurrentQuestion) m->CurrentQuestion = m->CurrentQuestion->next;
                        }
+               m->CurrentQuestion = mDNSNULL;
 
                // Scan our list of questions
                // (a) to see if there are any more that are worth accelerating, and
@@ -2484,7 +2520,7 @@ mDNSlocal void SendQueries(mDNS *const m)
                // which causes NextScheduledQuery to get (incorrectly) set to m->timenow. Setting it here is the right place, because the very
                // next thing we do is scan the list and call SetNextQueryTime() for every question we find, so we know we end up with the right value.
                m->NextScheduledQuery = m->timenow + 0x78000000;
-               for (q = m->Questions; q; q=q->next)
+               for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
                        {
                        if (mDNSOpaque16IsZero(q->TargetQID) && (q->SendQNow ||
                                (!q->Target.type && ActiveQuestion(q) && q->ThisQInterval <= maxExistingQuestionInterval && AccelerateThisQuery(m,q))))
@@ -2617,7 +2653,7 @@ mDNSlocal void SendQueries(mDNS *const m)
                        mDNSu32 answerforecast = 0;
                        
                        // Put query questions in this packet
-                       for (q = m->Questions; q; q=q->next)
+                       for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
                                {
                                if (mDNSOpaque16IsZero(q->TargetQID) && (q->SendQNow == intf->InterfaceID))
                                        {
@@ -2802,6 +2838,7 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
                        q->RecentAnswerPkts = 0;
                        q->ThisQInterval    = MaxQuestionInterval;
                        q->RequestUnicast   = mDNSfalse;
+                       debugf("AnswerCurrentQuestionWithResourceRecord: Set MaxQuestionInterval for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
                        }
 
        if (rr->DelayDelivery) return;          // We'll come back later when CacheRecordDeferredAdd() calls us
@@ -2878,7 +2915,10 @@ mDNSlocal mDNSs32 CheckForSoonToExpireRecords(mDNS *const m, const domainname *c
 mDNSlocal void CacheRecordAdd(mDNS *const m, CacheRecord *rr)
        {
        DNSQuestion *q;
-       for (q = m->Questions; q; q=q->next)
+
+       // We stop when we get to NewQuestions -- if we increment their CurrentAnswers/LargeAnswers/UniqueAnswers
+       // counters here we'll end up double-incrementing them when we do it again in AnswerNewQuestion().
+       for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
                {
                if (ResourceRecordAnswersQuestion(&rr->resrec, q))
                        {
@@ -2953,6 +2993,8 @@ mDNSlocal void NoCacheAnswer(mDNS *const m, CacheRecord *rr)
        if (m->CurrentQuestion)
                LogMsg("NoCacheAnswer ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
        m->CurrentQuestion = m->Questions;
+       // We do this for *all* questions, not stopping when we get to m->NewQuestions,
+       // since we're not caching the record and we'll get no opportunity to do this later
        while (m->CurrentQuestion)
                {
                DNSQuestion *q = m->CurrentQuestion;
@@ -2964,7 +3006,8 @@ mDNSlocal void NoCacheAnswer(mDNS *const m, CacheRecord *rr)
        m->CurrentQuestion = mDNSNULL;
        }
 
-// CacheRecordRmv is only called from CheckCacheExpiration, which is called from mDNS_Execute
+// CacheRecordRmv is only called from CheckCacheExpiration, which is called from mDNS_Execute.
+// Note that CacheRecordRmv is *only* called for records that are referenced by at least one active question.
 // If new questions are created as a result of invoking client callbacks, they will be added to
 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
 // rr is an existing cache CacheRecord that just expired and is being deleted
@@ -2977,6 +3020,9 @@ mDNSlocal void CacheRecordRmv(mDNS *const m, CacheRecord *rr)
        if (m->CurrentQuestion)
                LogMsg("CacheRecordRmv ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
        m->CurrentQuestion = m->Questions;
+
+       // We stop when we get to NewQuestions -- for new questions their CurrentAnswers/LargeAnswers/UniqueAnswers counters
+       // will all still be zero because we haven't yet gone through the cache counting how many answers we have for them.
        while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
                {
                DNSQuestion *q = m->CurrentQuestion;
@@ -3156,6 +3202,8 @@ mDNSlocal void AnswerNewQuestion(mDNS *const m)
                m->CurrentRecord = mDNSNULL;
                }
 
+       if (m->CurrentQuestion != q) debugf("AnswerNewQuestion: question deleted while giving LocalOnly record answers");
+
        if (m->CurrentQuestion == q)
                {
                CacheRecord *rr;
@@ -3186,19 +3234,23 @@ mDNSlocal void AnswerNewQuestion(mDNS *const m)
                                        ShouldQueryImmediately = mDNSfalse;
                }
 
+       if (m->CurrentQuestion != q) debugf("AnswerNewQuestion: question deleted while giving cache answers");
+
        if (m->CurrentQuestion == q && ShouldQueryImmediately && ActiveQuestion(q))
                {
+               debugf("AnswerNewQuestion: ShouldQueryImmediately %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
                q->ThisQInterval  = InitialQuestionInterval;
                q->LastQTime      = m->timenow - q->ThisQInterval;
-               if (mDNSOpaque16IsZero(q->TargetQID))
+               if (mDNSOpaque16IsZero(q->TargetQID))           // For mDNS, spread packets to avoid a burst of simultaneous queries
                        {
                        // Compute random delay in the range 1-6 seconds, then divide by 50 to get 20-120ms
                        if (!m->RandomQueryDelay)
                                m->RandomQueryDelay = (mDNSPlatformOneSecond + mDNSRandom(mDNSPlatformOneSecond*5) - 1) / 50 + 1;
                        q->LastQTime += m->RandomQueryDelay;
                        }
-               
-               m->NextScheduledQuery = m->timenow;
+
+               if (m->NextScheduledQuery - (q->LastQTime + q->ThisQInterval) > 0)
+                       m->NextScheduledQuery = (q->LastQTime + q->ThisQInterval);
                }
 
        m->CurrentQuestion = mDNSNULL;
@@ -3210,7 +3262,7 @@ mDNSlocal void AnswerNewQuestion(mDNS *const m)
 mDNSlocal void AnswerNewLocalOnlyQuestion(mDNS *const m)
        {
        DNSQuestion *q = m->NewLocalOnlyQuestions;              // Grab the question we're going to answer
-       m->NewLocalOnlyQuestions = q->next;                             // Advance NewQuestions to the next (if any)
+       m->NewLocalOnlyQuestions = q->next;                             // Advance NewLocalOnlyQuestions to the next (if any)
 
        debugf("AnswerNewLocalOnlyQuestion: Answering %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
 
@@ -3470,7 +3522,7 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
                                LogMsg("mDNS_Execute: SendQueries didn't send all its queries (%d - %d = %d) will try again in one second",
                                        m->timenow, m->NextScheduledQuery, m->timenow - m->NextScheduledQuery);
                                m->NextScheduledQuery = m->timenow + mDNSPlatformOneSecond;
-                               for (q = m->Questions; q; q=q->next)
+                               for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
                                        if (ActiveQuestion(q) && q->LastQTime + q->ThisQInterval - m->timenow <= 0)
                                                LogMsg("mDNS_Execute: SendQueries didn't send %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
                                }
@@ -3530,7 +3582,13 @@ mDNSlocal void SuspendLLQs(mDNS *m)
                        { q->ReqLease = 0; sendLLQRefresh(m, q); }
        }
 
-mDNSlocal void ActivateUnicastQuery(mDNS *const m, DNSQuestion *const question)
+// ActivateUnicastQuery() is called from three places:
+// 1. When a new question is created
+// 2. On wake from sleep
+// 3. When the DNS configuration changes
+// In case 1 we don't want to mess with our established ThisQInterval and LastQTime (ScheduleImmediately is false)
+// In cases 2 and 3 we do want to cause the question to be resent immediately (ScheduleImmediately is true)
+mDNSlocal void ActivateUnicastQuery(mDNS *const m, DNSQuestion *const question, mDNSBool ScheduleImmediately)
        {
        // For now this AutoTunnel stuff is specific to Mac OS X.
        // In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer
@@ -3550,13 +3608,22 @@ mDNSlocal void ActivateUnicastQuery(mDNS *const m, DNSQuestion *const question)
 
        if (!question->DuplicateOf)
                {
-               LogOperation("ActivateUnicastQuery: %##s %s%s",
-                       question->qname.c, DNSTypeName(question->qtype), question->AuthInfo ? " (Private)" : "");
+               LogOperation("ActivateUnicastQuery: %##s %s%s%s",
+                       question->qname.c, DNSTypeName(question->qtype), question->AuthInfo ? " (Private)" : "", ScheduleImmediately ? " ScheduleImmediately" : "");
                if (question->nta) { CancelGetZoneData(m, question->nta); question->nta = mDNSNULL; }
-               if (question->LongLived) { question->state = LLQ_InitialRequest; question->id = zeroOpaque64; }
-               question->ThisQInterval = InitialQuestionInterval;
-               question->LastQTime     = m->timenow - question->ThisQInterval;
-               SetNextQueryTime(m, question);
+               if (question->LongLived)
+                       {
+                       question->state = LLQ_InitialRequest;
+                       question->id = zeroOpaque64;
+                       question->servPort = zeroIPPort;
+                       if (question->tcp) { DisposeTCPConn(question->tcp); question->tcp = mDNSNULL; }
+                       }
+               if (ScheduleImmediately)
+                       {
+                       question->ThisQInterval = InitialQuestionInterval;
+                       question->LastQTime     = m->timenow - question->ThisQInterval;
+                       SetNextQueryTime(m, question);
+                       }
                }
        }
 
@@ -3609,7 +3676,7 @@ mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleepstate)
                        {
                        q = m->CurrentQuestion;
                        m->CurrentQuestion = m->CurrentQuestion->next;
-                       if (!mDNSOpaque16IsZero(q->TargetQID)) ActivateUnicastQuery(m, q);
+                       if (!mDNSOpaque16IsZero(q->TargetQID)) ActivateUnicastQuery(m, q, mDNStrue);
                        }
                // and reactivtate service registrations
                m->NextSRVUpdate = NonZeroTime(m->timenow + mDNSPlatformOneSecond);
@@ -4406,6 +4473,8 @@ mDNSexport CacheRecord *CreateNewCacheEntry(mDNS *const m, const mDNSu32 slot, C
                default:           RDLength = m->rec.r.resrec.rdlength; break;
                }
 
+       if (!m->rec.r.resrec.InterfaceID) debugf("CreateNewCacheEntry %s", CRDisplayString(m, &m->rec.r));
+
        //if (RDLength > InlineCacheRDSize)
        //      LogOperation("Rdata len %4d > InlineCacheRDSize %d %s", RDLength, InlineCacheRDSize, CRDisplayString(m, &m->rec.r));
 
@@ -4525,7 +4594,9 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
        // All records in a DNS response packet are treated as equally valid statements of truth. If we want
        // to guard against spoof responses, then the only credible protection against that is cryptographic
        // security, e.g. DNSSEC., not worring about which section in the spoof packet contained the record
-       int totalrecords = response->h.numAnswers + response->h.numAuthorities + response->h.numAdditionals;
+       int firstauthority  =                   response->h.numAnswers;
+       int firstadditional = firstauthority  + response->h.numAuthorities;
+       int totalrecords    = firstadditional + response->h.numAdditionals;
        const mDNSu8 *ptr = response->data;
 
        // Currently used only for display in debugging message
@@ -4589,9 +4660,12 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
                // (Note that just because we are willing to cache something, that doesn't necessarily make it a trustworthy answer
                // to any specific question -- any code reading records from the cache needs to make that determination for itself.)
 
-               const mDNSu8 RecordType = (mDNSu8)((i < response->h.numAnswers) ? kDNSRecordTypePacketAns : kDNSRecordTypePacketAdd);
+               const mDNSu8 RecordType =
+                       (i < firstauthority ) ? (mDNSu8)kDNSRecordTypePacketAns  :
+                       (i < firstadditional) ? (mDNSu8)kDNSRecordTypePacketAuth : (mDNSu8)kDNSRecordTypePacketAdd;
                ptr = GetLargeResourceRecord(m, response, ptr, end, InterfaceID, RecordType, &m->rec);
                if (!ptr) goto exit;            // Break out of the loop and clean up our CacheFlushRecords list before exiting
+
                // Don't want to cache OPT or TSIG pseudo-RRs
                if (m->rec.r.resrec.rrtype == kDNSType_OPT || m->rec.r.resrec.rrtype == kDNSType_TSIG)
                        { m->rec.r.resrec.RecordType = 0; continue; }
@@ -4691,9 +4765,21 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
                                }
                        }
 
+               if (!AcceptableResponse)
+                       {
+                       CacheRecord *cr;
+                       for (cr = CacheFlushRecords; cr != (CacheRecord*)1; cr = cr->NextInCFList)
+                               {
+                               domainname *target = GetRRDomainNameTarget(&cr->resrec);
+                               if (target && cr->resrec.rdatahash == m->rec.r.resrec.namehash && SameDomainName(target, m->rec.r.resrec.name))
+                                       { AcceptableResponse = mDNStrue; break; }
+                               }
+                       }
+
                // 2. See if we want to add this packet resource record to our cache
                // We only try to cache answers if we have a cache to put them in
                // Also, we ignore any apparent attempts at cache poisoning unicast to us that do not answer any outstanding active query
+               if (!AcceptableResponse) debugf("mDNSCoreReceiveResponse ignoring %s", CRDisplayString(m, &m->rec.r));
                if (m->rrcache_size && AcceptableResponse)
                        {
                        const mDNSu32 slot = HashSlot(m->rec.r.resrec.name);
@@ -5198,6 +5284,9 @@ mDNSlocal void LLQNATCallback(mDNS *m, NATTraversalInfo *n)
        for (q = m->Questions; q; q=q->next)
                if (ActiveQuestion(q) && !mDNSOpaque16IsZero(q->TargetQID) && q->LongLived)
                        startLLQHandshake(m, q);        // If ExternalPort is zero, will do StartLLQPolling instead
+#if APPLE_OSX_mDNSResponder
+       UpdateAutoTunnelDomainStatuses(m);
+#endif
        mDNS_Unlock(m);
        }
 
@@ -5216,16 +5305,11 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
                question->TargetQID  = zeroID;
                }
 
+       question->TargetQID =
 #ifndef UNICAST_DISABLED
-       // If the client has specified 'kDNSServiceFlagsForceMulticast'
-       // then we do a multicast query on that interface, even for unicast domains.
-       if (question->InterfaceID == mDNSInterface_LocalOnly || question->ForceMCast || IsLocalDomain(&question->qname))
-               question->TargetQID = zeroID;
-       else
-               question->TargetQID = mDNS_NewMessageID(m);
-#else
-    question->TargetQID = zeroID;
+               (question->InterfaceID != mDNSInterface_LocalOnly && !question->ForceMCast && !IsLocalDomain(&question->qname)) ? mDNS_NewMessageID(m) :
 #endif // UNICAST_DISABLED
+               zeroID;
 
        debugf("mDNS_StartQuery: %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
 
@@ -5312,14 +5396,11 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
                for (i=0; i<DupSuppressInfoSize; i++)
                        question->DupSuppress[i].InterfaceID = mDNSNULL;
 
-               if (!question->DuplicateOf)
-                       debugf("mDNS_StartQuery: Question %##s (%s) %p %d (%p) started",
-                               question->qname.c, DNSTypeName(question->qtype), question->InterfaceID,
-                               question->LastQTime + question->ThisQInterval - m->timenow, question);
-               else
-                       debugf("mDNS_StartQuery: Question %##s (%s) %p %d (%p) duplicate of (%p)",
-                               question->qname.c, DNSTypeName(question->qtype), question->InterfaceID,
-                               question->LastQTime + question->ThisQInterval - m->timenow, question, question->DuplicateOf);
+               debugf("mDNS_StartQuery: Question %##s (%s) Interface %p Now %d Send in %d Answer in %d (%p) %s (%p)",
+                       question->qname.c, DNSTypeName(question->qtype), question->InterfaceID, m->timenow,
+                       question->LastQTime + question->ThisQInterval - m->timenow,
+                       question->DelayAnswering ? question->DelayAnswering - m->timenow : 0,
+                       question, question->DuplicateOf ? "duplicate of" : "not duplicate", question->DuplicateOf);
 
                if (question->InterfaceID == mDNSInterface_LocalOnly)
                        {
@@ -5338,7 +5419,7 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
                        if (!mDNSOpaque16IsZero(question->TargetQID))
                                {
                                question->qDNSServer = GetServerForName(m, &question->qname);
-                               ActivateUnicastQuery(m, question);
+                               ActivateUnicastQuery(m, question, mDNSfalse);
 
                                // If long-lived query, and we don't have our NAT mapping active, start it now
                                if (question->LongLived && !m->LLQNAT.clientContext)
@@ -5350,6 +5431,12 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
                                        m->LLQNAT.clientContext  = (void*)1; // Means LLQ NAT Traversal is active
                                        mDNS_StartNATOperation_internal(m, &m->LLQNAT);
                                        }
+                                       
+#if APPLE_OSX_mDNSResponder
+                               if (question->LongLived)
+                                       UpdateAutoTunnelDomainStatuses(m);
+#endif
+                                       
                                }
                        SetNextQueryTime(m,question);
                        }
@@ -5475,6 +5562,9 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
                                question->tcp           = mDNSNULL;
                                }
                        }
+#if APPLE_OSX_mDNSResponder
+               UpdateAutoTunnelDomainStatuses(m);
+#endif
                }
 
        return(mStatus_NoError);
@@ -7062,7 +7152,7 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
                                        s, s ? &s->addr : mDNSNULL, mDNSVal16(s ? s->port : zeroIPPort), s ? s->domain.c : (mDNSu8*)"",
                                        q->qname.c, DNSTypeName(q->qtype));
                                q->qDNSServer = s;
-                               ActivateUnicastQuery(m, q);
+                               ActivateUnicastQuery(m, q, mDNStrue);
                                }
                        }
 
index 81bcedbc84c7b9f33d83eef104e56fd609b3d50c..73010874edb655c971ec9edc7377222e13164bcd 100755 (executable)
@@ -17,6 +17,9 @@
     Change History (most recent first):
 
 $Log: mDNSDebug.h,v $
+Revision 1.39  2008/02/26 21:17:11  cheshire
+Grouped all user settings together near the start of the file; added LogTimeStamps option
+
 Revision 1.38  2007/12/13 20:27:07  cheshire
 Remove unused VerifySameNameAssumptions symbol
 
@@ -136,6 +139,32 @@ Merge in license terms from Quinn's copy, in preparation for Darwin release
 //    warning: repeated `#' flag in format              (for %##s             -- DNS name string format)
 //    warning: double format, pointer arg (arg 2)       (for %.4a, %.16a, %#a -- IP address formats)
 #define MDNS_CHECK_PRINTF_STYLE_FUNCTIONS 0
+
+typedef enum
+       {
+       MDNS_LOG_NONE,
+//     MDNS_LOG_ERROR,
+//     MDNS_LOG_WARN,
+//     MDNS_LOG_INFO,
+//     MDNS_LOG_DEBUG,
+       MDNS_LOG_VERBOSE_DEBUG
+       } LogLevel_t;
+
+#define MDNS_LOG_INITIAL_LEVEL MDNS_LOG_NONE
+
+// Set this symbol to 1 to answer remote queries for our Address, reverse mapping PTR, and HINFO records
+#define ANSWER_REMOTE_HOSTNAME_QUERIES 0
+
+// Set this symbol to 1 to do extra debug checks on malloc() and free()
+// Set this symbol to 2 to write a log message for every malloc() and free()
+#define MACOSX_MDNS_MALLOC_DEBUGGING 0
+
+#define LogAllOperations 0
+#define LogTimeStamps 0
+#define ForceAlerts 0
+
+// Developer-settings section ends here
+
 #if MDNS_CHECK_PRINTF_STYLE_FUNCTIONS
 #define IS_A_PRINTF_STYLE_FUNCTION(F,A) __attribute__ ((format(printf,F,A)))
 #else
@@ -198,18 +227,6 @@ extern void verbosedebugf_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1
 #endif
 
 // LogMsg is used even in shipping code, to write truly serious error messages to syslog (or equivalent)
-typedef enum
-       {
-       MDNS_LOG_NONE,
-//     MDNS_LOG_ERROR,
-//     MDNS_LOG_WARN,
-//     MDNS_LOG_INFO,
-//     MDNS_LOG_DEBUG,
-       MDNS_LOG_VERBOSE_DEBUG
-       } LogLevel_t;
-
-#define MDNS_LOG_INITIAL_LEVEL MDNS_LOG_NONE
-
 extern LogLevel_t mDNS_LogLevel;
 extern int        mDNS_DebugMode;      // If non-zero, LogMsg() writes to stderr instead of syslog
 extern const char ProgramName[];       // Program Name for use with LogMsgIdent
@@ -219,13 +236,6 @@ extern void LogMsgIdent(const char *ident, const char *format, ...) IS_A_PRINTF_
 extern void LogMsgNoIdent(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
 extern void SigLogLevel(void);
 
-// Set this symbol to 1 to answer remote queries for our Address, reverse mapping PTR, and HINFO records
-#define ANSWER_REMOTE_HOSTNAME_QUERIES 0
-
-// Set this symbol to 1 to do extra debug checks on malloc() and free()
-// Set this symbol to 2 to write a log message for every malloc() and free()
-#define MACOSX_MDNS_MALLOC_DEBUGGING 0
-
 #if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
 extern void *mallocL(char *msg, unsigned int size);
 extern void freeL(char *msg, void *x);
@@ -237,16 +247,12 @@ extern void udns_validatelists(void *const v);
 #define freeL(X,Y) free(Y)
 #endif
 
-#define LogAllOperations 0
-
 #if LogAllOperations
 #define LogOperation LogMsg
 #else
 #define        LogOperation debugf
 #endif
 
-#define ForceAlerts 0
-
 #ifdef __cplusplus
        }
 #endif
index a67e1f37bfe182444630f55dc33388bd2bb92310..72b9e1f27bb4b51460230a6a48ae152fb6c84b97 100755 (executable)
     Change History (most recent first):
 
 $Log: mDNSEmbeddedAPI.h,v $
+Revision 1.468  2008/03/06 02:48:34  mcguire
+<rdar://problem/5321824> write status to the DS
+
+Revision 1.467  2008/02/26 20:48:46  cheshire
+Need parentheses around use of macro argument in mDNS_TimeNow_NoLock(m)
+
+Revision 1.466  2008/02/21 21:36:32  cheshire
+Updated comment about record type values (kDNSRecordTypePacketAns/Auth/Add)
+
+Revision 1.465  2008/02/20 00:39:05  mcguire
+<rdar://problem/5427102> Some device info XML blobs too large
+
+Revision 1.464  2008/01/31 23:33:29  mcguire
+<rdar://problem/5614450> changes to build using gcc 4.2 with -Werror
+
 Revision 1.463  2007/12/17 23:53:25  cheshire
 Added DNSDigest_SignMessageHostByteOrder, for signing messages not yet converted to network byte order
 
@@ -892,9 +907,11 @@ enum
        mStatus_BadKey                    = -65561,
        mStatus_TransientErr              = -65562,     // transient failures, e.g. sending packets shortly after a network transition or wake from sleep
        mStatus_ServiceNotRunning         = -65563,     // Background daemon not running
-       mStatus_NATPortMappingUnsupported = -65564,     // No NAT or if the NAT doesn't support NAT-PMP or UPnP
+       mStatus_NATPortMappingUnsupported = -65564,     // NAT doesn't support NAT-PMP or UPnP
        mStatus_NATPortMappingDisabled    = -65565,     // NAT supports NAT-PMP or UPnP but it's disabled by the administrator
-       // -65566 to -65786 currently unused; available for allocation
+       mStatus_NoRouter                  = -65566,
+       mStatus_PollingMode               = -65567,
+       // -65568 to -65786 currently unused; available for allocation
 
        // tcp connection status
        mStatus_ConnPending       = -65787,
@@ -1070,7 +1087,7 @@ typedef struct tcpInfo_t
 // Cache Resource Records (received from the network):
 // There are four basic types: Answer, Unique Answer, Additional, Unique Additional
 // Bit 7 (the top bit) of kDNSRecordType is always set for Cache Resource Records; always clear for Authoritative Resource Records
-// Bit 6 (value 0x40) is set for answer records; clear for additional records
+// Bit 6 (value 0x40) is set for answer records; clear for authority/additional records
 // Bit 5 (value 0x20) is set for records received with the kDNSClass_UniqueRRSet
 
 enum
@@ -1271,7 +1288,7 @@ typedef enum
        LNTPortMapDeleteOp  = 4
        } LNTOp_t;
 
-#define LNT_MAXBUFSIZE 4096
+#define LNT_MAXBUFSIZE 8192
 typedef struct tcpLNTInfo_struct tcpLNTInfo;
 struct tcpLNTInfo_struct
        {
@@ -2493,8 +2510,9 @@ extern void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr,  const
 extern DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSAddr *addr, const mDNSIPPort port);
 extern void mDNS_AddSearchDomain(const domainname *const domain);
 
+// We use ((void *)0) here instead of mDNSNULL to avoid compile warnings on gcc 4.2
 #define mDNS_AddSearchDomain_CString(X) \
-       do { domainname d__; if ((X) && MakeDomainNameFromDNSNameString(&d__, (X)) && d__.c[0]) mDNS_AddSearchDomain(&d__); } while(0)
+       do { domainname d__; if (((X) != (void*)0) && MakeDomainNameFromDNSNameString(&d__, (X)) && d__.c[0]) mDNS_AddSearchDomain(&d__); } while(0)
 
 // Routines called by the core, exported by DNSDigest.c
 
@@ -2580,7 +2598,7 @@ extern mDNSu32  mDNSPlatformRandomSeed  (void);
 extern mStatus  mDNSPlatformTimeInit    (void);
 extern mDNSs32  mDNSPlatformRawTime     (void);
 extern mDNSs32  mDNSPlatformUTC         (void);
-#define mDNS_TimeNow_NoLock(m) (mDNSPlatformRawTime() + m->timenow_adjust)
+#define mDNS_TimeNow_NoLock(m) (mDNSPlatformRawTime() + (m)->timenow_adjust)
 
 #if MDNS_DEBUGMSGS
 extern void    mDNSPlatformWriteDebugMsg(const char *msg);
@@ -2707,6 +2725,7 @@ extern void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheRecord *
 extern void AutoTunnelCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord);
 extern void AddNewClientTunnel(mDNS *const m, DNSQuestion *const q);
 extern void SetupLocalAutoTunnelInterface_internal(mDNS *const m);
+extern void UpdateAutoTunnelDomainStatuses(const mDNS *const m);
 #endif
 
 // ***************************************************************************
index bcf8ddffae6c1c7c44da7c7454a24ef31a75bfe8..e063fc58ccc281adcd962c72adbd9ebede097c7b 100755 (executable)
        Change History (most recent first):
 
 $Log: uDNS.c,v $
+Revision 1.553.2.1  2008/03/14 20:11:25  mcguire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+Make sure we add the record when sending LLQ refreshes
+
+Revision 1.553  2008/03/06 02:48:34  mcguire
+<rdar://problem/5321824> write status to the DS
+
+Revision 1.552  2008/03/05 01:56:42  cheshire
+<rdar://problem/5687667> BTMM: Don't fallback to unencrypted operations when SRV lookup fails
+
+Revision 1.551  2008/03/01 01:43:04  cheshire
+<rdar://problem/5631565> BTMM: Lots of "Error getting external address 3" when double-NATed prevents sleep
+Added code to suppress logging of multiple identical error results
+
+Revision 1.550  2008/03/01 01:34:47  cheshire
+<rdar://problem/5736313> BTMM: Double-NAT'd machines register all but AutoTunnel v4 address records
+Further refinements
+
+Revision 1.549  2008/02/29 01:35:37  mcguire
+<rdar://problem/5736313> BTMM: Double-NAT'd machines register all but AutoTunnel v4 address records
+
+Revision 1.548  2008/02/20 23:54:18  cheshire
+<rdar://problem/5661518> "Failed to obtain NAT port mapping" syslog messages
+Improved log message so it tells us more about what's going on
+
+Revision 1.547  2008/02/20 00:41:09  cheshire
+Change "PrivateQueryGotZoneData ... invoked with error code" from LogMsg to LogOperation
+
+Revision 1.546  2008/02/19 23:26:50  cheshire
+<rdar://problem/5661661> BTMM: Too many members.mac.com SOA queries
+
 Revision 1.545  2007/12/22 02:25:29  cheshire
 <rdar://problem/5661128> Records and Services sometimes not re-registering on wake from sleep
 
@@ -1461,7 +1492,11 @@ mDNSlocal void ClearUPnPState(mDNS *const m)
 
 mDNSexport void natTraversalHandleAddressReply(mDNS *const m, mDNSu16 err, mDNSv4Addr ExtAddr)
        {
-       if (err) LogMsg("Error getting external address %d", err);
+       static mDNSu16 last_err;
+       if (err)
+               {
+               if (err != last_err) LogMsg("Error getting external address %d", err);
+               }
        else if (!mDNSSameIPv4Address(m->ExternalAddress, ExtAddr))
                {
                LogOperation("Received external IP address %.4a from NAT", &ExtAddr);
@@ -1477,6 +1512,8 @@ mDNSexport void natTraversalHandleAddressReply(mDNS *const m, mDNSu16 err, mDNSv
        m->retryGetAddr = m->timenow + m->retryIntervalGetAddr;
        if (m->NextScheduledNATOp - m->retryIntervalGetAddr > 0)
                m->NextScheduledNATOp = m->retryIntervalGetAddr;
+
+       last_err = err;
        }
 
 // Both places that call NATSetNextRenewalTime() update m->NextScheduledNATOp correctly afterwards
@@ -1635,6 +1672,9 @@ mDNSlocal void StartLLQPolling(mDNS *const m, DNSQuestion *q)
        // we risk causing spurious "SendQueries didn't send all its queries" log messages
        q->LastQTime     = m->timenow - q->ThisQInterval + 1;
        SetNextQueryTime(m, q);
+#if APPLE_OSX_mDNSResponder
+       UpdateAutoTunnelDomainStatuses(m);
+#endif
        }
 
 mDNSlocal mDNSu8 *putLLQ(DNSMessage *const msg, mDNSu8 *ptr, const DNSQuestion *const question, const LLQOptData *const data, mDNSBool includeQuestion)
@@ -1789,6 +1829,9 @@ mDNSlocal void recvSetupResponse(mDNS *const m, mDNSu8 rcode, DNSQuestion *const
                q->state         = LLQ_Established;
                q->ntries        = 0;
                SetLLQTimer(m, q, llq);
+#if APPLE_OSX_mDNSResponder
+               UpdateAutoTunnelDomainStatuses(m);
+#endif
                }
        }
 
@@ -2426,12 +2469,17 @@ mDNSlocal void GetZoneData_QuestionCallback(mDNS *const m, DNSQuestion *question
                {
                debugf("GetZoneData GOT SRV %s", RRDisplayString(m, answer));
                mDNS_StopQuery(m, question);
+// Right now we don't want to fail back to non-encrypted operations
+// If the AuthInfo has the AutoTunnel field set, then we want private or nothing
+// <rdar://problem/5687667> BTMM: Don't fallback to unencrypted operations when SRV lookup fails
+#if 0
                if (!answer->rdlength && zd->ZonePrivate && zd->ZoneService != ZoneServiceQuery)
                        {
                        zd->ZonePrivate = mDNSfalse;    // Causes ZoneDataSRV() to yield a different SRV name when building the query
                        GetZoneData_StartQuery(m, zd, kDNSType_SRV);            // Try again, non-private this time
                        }
                else
+#endif
                        {
                        if (answer->rdlength)
                                {
@@ -2515,7 +2563,7 @@ mDNSexport ZoneData *StartGetZoneData(mDNS *const m, const domainname *const nam
        zd->Host.c[0]        = 0;
        zd->Port             = zeroIPPort;
        zd->Addr             = zeroAddr;
-       zd->ZonePrivate      = AuthInfo ? mDNStrue : mDNSfalse;
+       zd->ZonePrivate      = AuthInfo && AuthInfo->AutoTunnel ? mDNStrue : mDNSfalse;
        zd->ZoneDataCallback = callback;
        zd->ZoneDataContext  = ZoneDataContext;
 
@@ -3131,6 +3179,9 @@ mDNSexport void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, co
 
                UpdateSRVRecords(m);
                GetStaticHostname(m);   // look up reverse map record to find any static hostnames for our IP address
+#if APPLE_OSX_mDNSResponder
+               UpdateAutoTunnelDomainStatuses(m);
+#endif
                }
 
        mDNS_Unlock(m);
@@ -3719,6 +3770,27 @@ mDNSlocal const domainname *DNSRelayTestQuestion = (const domainname*)
        "\x1" "1" "\x1" "0" "\x1" "0" "\x3" "127" "\xa" "dnsbugtest"
        "\x1" "1" "\x1" "0" "\x1" "0" "\x3" "127" "\x7" "in-addr" "\x4" "arpa";
 
+// See comments above for DNSRelayTestQuestion
+// If this is the kind of query that has the risk of crashing buggy DNS servers, we do a test question first
+mDNSlocal mDNSBool NoTestQuery(DNSQuestion *q)
+       {
+       int i;
+       mDNSu8 *p = q->qname.c;
+       if (q->AuthInfo) return(mDNStrue);              // Don't need a test query for private queries sent directly to authoritative server over TLS/TCP
+       if (q->qtype != kDNSType_PTR) return(mDNStrue);         // Don't need a test query for any non-PTR queries
+       for (i=0; i<4; i++)             // If qname does not begin with num.num.num.num, can't skip the test query
+               {
+               if (p[0] < 1 || p[0] > 3) return(mDNSfalse);
+               if (              p[1] < '0' || p[1] > '9' ) return(mDNSfalse);
+               if (p[0] >= 2 && (p[2] < '0' || p[2] > '9')) return(mDNSfalse);
+               if (p[0] >= 3 && (p[3] < '0' || p[3] > '9')) return(mDNSfalse);
+               p += 1 + p[0];
+               }
+       // If remainder of qname is ".in-addr.arpa.", this is a vanilla reverse-mapping query and
+       // we can safely do it without needing a test query first, otherwise we need the test query.
+       return(SameDomainName((domainname*)p, (const domainname*)"\x7" "in-addr" "\x4" "arpa"));
+       }
+
 // Returns mDNStrue if response was handled
 mDNSlocal mDNSBool uDNS_ReceiveTestQuestionResponse(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
        const mDNSAddr *const srcaddr, const mDNSIPPort srcport)
@@ -3747,15 +3819,15 @@ mDNSlocal mDNSBool uDNS_ReceiveTestQuestionResponse(mDNS *const m, DNSMessage *c
                if (mDNSSameAddress(srcaddr, &s->addr) && mDNSSameIPPort(srcport, s->port) && s->teststate != result)
                        {
                        DNSQuestion *q;
-                       if (s->teststate != result)
-                               {
-                               s->teststate = result;
-                               if (result == DNSServer_Passed) LogOperation("DNS Server %#a:%d passed", srcaddr, mDNSVal16(srcport));
-                               else LogMsg("NOTE: Wide-Area Service Discovery disabled to avoid crashing defective DNS relay %#a:%d", srcaddr, mDNSVal16(srcport));
-                               }
+                       s->teststate = result;
+                       if (result == DNSServer_Passed) LogOperation("DNS Server %#a:%d passed", srcaddr, mDNSVal16(srcport));
+                       else LogMsg("NOTE: Wide-Area Service Discovery disabled to avoid crashing defective DNS relay %#a:%d", srcaddr, mDNSVal16(srcport));
+
+                       // If this server has just changed state from DNSServer_Untested to DNSServer_Passed, then retrigger any waiting questions.
+                       // We use the NoTestQuery() test so that we only retrigger questions that were actually blocked waiting for this test to complete.
                        if (result == DNSServer_Passed)         // Unblock any questions that were waiting for this result
                                for (q = m->Questions; q; q=q->next)
-                                       if (q->qDNSServer == s)
+                                       if (q->qDNSServer == s && !NoTestQuery(q))
                                                { q->LastQTime = m->timenow - q->ThisQInterval; m->NextScheduledQuery = m->timenow; }
                        }
 
@@ -3882,6 +3954,12 @@ mDNSexport void sendLLQRefresh(mDNS *m, DNSQuestion *q)
        InitializeDNSMessage(&m->omsg.h, q->TargetQID, uQueryFlags);
        end = putLLQ(&m->omsg, m->omsg.data, q, &llq, mDNStrue);
        if (!end) { LogMsg("sendLLQRefresh: putLLQ failed %##s (%s)", q->qname.c, DNSTypeName(q->qtype)); return; }
+
+       // Note that we (conditionally) add HINFO and TSIG here, since the question might be going away,
+       // so we may not be able to reference it (most importantly it's AuthInfo) when we actually send the message
+       end = putHINFO(m, &m->omsg, end, q->AuthInfo);
+       if (!end) { LogMsg("sendLLQRefresh: putHINFO failed %##s (%s)", q->qname.c, DNSTypeName(q->qtype)); return; }
+
        if (q->AuthInfo)
                {
                DNSDigest_SignMessageHostByteOrder(&m->omsg, &end, q->AuthInfo);
@@ -3951,9 +4029,12 @@ mDNSlocal void PrivateQueryGotZoneData(mDNS *const m, mStatus err, const ZoneDat
        // we use for cleaning up if our LLQ is cancelled *before* the GetZoneData operation has completes).
        q->nta = mDNSNULL;
 
-       if (err)
+       if (err || !zoneInfo || mDNSAddressIsZero(&zoneInfo->Addr) || mDNSIPPortIsZero(zoneInfo->Port))
                {
-               LogMsg("ERROR: PrivateQueryGotZoneData %##s (%s) invoked with error code %ld", q->qname.c, DNSTypeName(q->qtype), err);
+               LogOperation("ERROR: PrivateQueryGotZoneData %##s (%s) invoked with error code %ld %p %#a:%d",
+                       q->qname.c, DNSTypeName(q->qtype), err, zoneInfo,
+                       zoneInfo ? &zoneInfo->Addr : mDNSNULL,
+                       zoneInfo ? mDNSVal16(zoneInfo->Port) : 0);
                return;
                }
 
@@ -4250,27 +4331,6 @@ mDNSexport mStatus uDNS_UpdateRecord(mDNS *m, AuthRecord *rr)
 #pragma mark - Periodic Execution Routines
 #endif
 
-// See comments above for DNSRelayTestQuestion
-// If this is the kind of query that has the risk of crashing buggy DNS servers, we do a test question first
-mDNSlocal mDNSBool NoTestQuery(DNSQuestion *q)
-       {
-       int i;
-       mDNSu8 *p = q->qname.c;
-       if (q->AuthInfo) return(mDNStrue);              // Don't need a test query for private queries sent directly to authoritative server over TLS/TCP
-       if (q->qtype != kDNSType_PTR) return(mDNStrue);         // Don't need a test query for any non-PTR queries
-       for (i=0; i<4; i++)             // If qname does not begin with num.num.num.num, can't skip the test query
-               {
-               if (p[0] < 1 || p[0] > 3) return(mDNSfalse);
-               if (              p[1] < '0' || p[1] > '9' ) return(mDNSfalse);
-               if (p[0] >= 2 && (p[2] < '0' || p[2] > '9')) return(mDNSfalse);
-               if (p[0] >= 3 && (p[3] < '0' || p[3] > '9')) return(mDNSfalse);
-               p += 1 + p[0];
-               }
-       // If remainder of qname is ".in-addr.arpa.", this is a vanilla reverse-mapping query and
-       // we can safely do it without needing a test query first, otherwise we need the test query.
-       return(SameDomainName((domainname*)p, (const domainname*)"\x7" "in-addr" "\x4" "arpa"));
-       }
-
 // The question to be checked is not passed in as an explicit parameter;
 // instead it is implicit that the question to be checked is m->CurrentQuestion.
 mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
@@ -4300,13 +4360,13 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
                        {
                        mDNSu8 *end = m->omsg.data;
                        mStatus err = mStatus_NoError;
-                       DomainAuthInfo *private = mDNSNULL;
+                       mDNSBool private = mDNSfalse;
 
                        if (q->qDNSServer->teststate != DNSServer_Untested || NoTestQuery(q))
                                {
                                InitializeDNSMessage(&m->omsg.h, q->TargetQID, uQueryFlags);
                                end = putQuestion(&m->omsg, m->omsg.data, m->omsg.data + AbsoluteMaxDNSMessageData, &q->qname, q->qtype, q->qclass);
-                               private = q->AuthInfo;
+                               private = (q->AuthInfo && q->AuthInfo->AutoTunnel);
                                }
                        else if (m->timenow - q->qDNSServer->lasttest >= INIT_UCAST_POLL_INTERVAL)      // Make sure at least three seconds has elapsed since last test query
                                {
@@ -4468,22 +4528,24 @@ mDNSlocal void CheckNATMappings(mDNS *m)
                // and (3) we have new data to give the client that's changed since the last callback
                if (!mDNSIPv4AddressIsZero(m->ExternalAddress) || m->retryIntervalGetAddr > NATMAP_INIT_RETRY * 8)
                        {
+                       const mStatus EffectiveResult = cur->NewResult ? cur->NewResult : mDNSv4AddrIsRFC1918(&m->ExternalAddress) ? mStatus_DoubleNAT : mStatus_NoError;
                        const mDNSIPPort ExternalPort = HaveRoutable ? cur->IntPort :
                                !mDNSIPv4AddressIsZero(m->ExternalAddress) && cur->ExpiryTime ? cur->RequestedPort : zeroIPPort;
                        if (!cur->Protocol || HaveRoutable || cur->ExpiryTime || cur->retryInterval > NATMAP_INIT_RETRY * 8)
                                if (!mDNSSameIPv4Address(cur->ExternalAddress, m->ExternalAddress) ||
                                        !mDNSSameIPPort     (cur->ExternalPort,       ExternalPort)    ||
-                                       cur->Result != cur->NewResult)
+                                       cur->Result != EffectiveResult)
                                        {
                                        //LogMsg("NAT callback %d %d %d", cur->Protocol, cur->ExpiryTime, cur->retryInterval);
                                        if (cur->Protocol && mDNSIPPortIsZero(ExternalPort) && !mDNSIPv4AddressIsZero(m->Router.ip.v4))
-                                               LogMsg("Failed to obtain NAT port mapping from router %#a external address %.4a internal port %d",
-                                                       &m->Router, &m->ExternalAddress, mDNSVal16(cur->IntPort));
+                                               LogMsg("Failed to obtain NAT port mapping %p from router %#a external address %.4a internal port %d error %d",
+                                                       cur, &m->Router, &m->ExternalAddress, mDNSVal16(cur->IntPort), EffectiveResult);
+
                                        cur->ExternalAddress = m->ExternalAddress;
                                        cur->ExternalPort    = ExternalPort;
                                        cur->Lifetime        = cur->ExpiryTime && !mDNSIPPortIsZero(ExternalPort) ?
                                                (cur->ExpiryTime - m->timenow + mDNSPlatformOneSecond/2) / mDNSPlatformOneSecond : 0;
-                                       cur->Result          = cur->NewResult;
+                                       cur->Result          = EffectiveResult;
                                        mDNS_DropLockBeforeCallback();          // Allow client to legally make mDNS API calls from the callback
                                        if (cur->clientCallback)
                                                cur->clientCallback(m, cur);
index 50397751d2de7c447c7a59a558e49aecfca24e35..cb01007a7efde28f3c4631080b94a662b91e5091 100644 (file)
@@ -6,6 +6,8 @@
   <string>com.apple.mDNSResponderHelper</string>
   <key>OnDemand</key>
   <true/>
+  <key>HopefullyExitsLast</key>
+  <true/>
   <key>ProgramArguments</key>
   <array>
     <string>/usr/sbin/mDNSResponderHelper</string>
index 8f35709eaae42d94f9d4d27114fee85b6e4b8ca9..a36f31db57e664fc621b886aa4dd6ece70ddeadd 100644 (file)
@@ -6,10 +6,12 @@
        <string>com.apple.mDNSResponder</string>
        <key>OnDemand</key>
        <false/>
-        <key>UserName</key>
-        <string>_mdnsresponder</string>
-        <key>GroupName</key>
-        <string>_mdnsresponder</string>
+       <key>HopefullyExitsFirst</key>
+       <true/>
+       <key>UserName</key>
+       <string>_mdnsresponder</string>
+       <key>GroupName</key>
+       <string>_mdnsresponder</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/sbin/mDNSResponder</string>
index 8acaf295b776a647fc5ea1539660b6bde4e1f297..f36174fc7faa1cba5917e3fe9aafc364123a0e1b 100644 (file)
     Change History (most recent first):
 
 $Log: daemon.c,v $
+Revision 1.358  2008/03/06 21:26:11  cheshire
+Moved duplicated STRINGIFY macro from individual C files to DNSCommon.h
+
+Revision 1.357  2008/02/13 17:40:43  cheshire
+<rdar://problem/5740501> Investigate mysterious SIGABRTs in mDNSResponder
+
 Revision 1.356  2007/12/18 00:28:56  cheshire
 <rdar://problem/5526800> BTMM: Need to deregister records and services on shutdown/sleep
 Error in ReadyForSleep() logic -- missing "not" in "!mDNSOpaque16IsZero(q->TargetQID)"
@@ -378,15 +384,6 @@ Revision 1.261  2006/01/06 01:22:28  cheshire
 #include <DNSServiceDiscovery/DNSServiceDiscovery.h>
 #include "helper.h"
 
-//*************************************************************************************************************
-// Macros
-
-// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
-// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
-// To expand "version" to its value before making the string, use STRINGIFY(version) instead
-#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) #s
-#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
-
 //*************************************************************************************************************
 // Globals
 
@@ -1985,6 +1982,13 @@ mDNSlocal void HandleSIG(int sig)
                }
        }
 
+mDNSlocal void CatchABRT(int sig)
+       {
+       LogMsg("Received SIGABRT %d", sig);
+       sleep(1);                                       // Pause to make sure syslog gets the message
+       while(1) *(long*)0 = 0;         // Generate a CrashReporter stack trace so we can find out what library called abort();
+       }
+
 mDNSlocal void INFOCallback(void)
        {
        mDNSs32 utc = mDNSPlatformUTC();
@@ -2611,6 +2615,7 @@ mDNSexport int main(int argc, char **argv)
 
        signal(SIGHUP,  HandleSIG);             // (Debugging) Purge the cache to check for cache handling bugs
        signal(SIGINT,  HandleSIG);             // Ctrl-C: Detach from Mach BootstrapService and exit cleanly
+       signal(SIGABRT, CatchABRT);             // For debugging -- SIGABRT should never happen
        signal(SIGPIPE, SIG_IGN  );             // Don't want SIGPIPE signals -- we'll handle EPIPE errors directly
        signal(SIGTERM, HandleSIG);             // Machine shutting down: Detach from and exit cleanly like Ctrl-C
        signal(SIGINFO, HandleSIG);             // (Debugging) Write state snapshot to syslog
index 8f4b8f8566b14a64cee4776a1e42f234f9bbc79a..d3ad6b1859f20bbea571f0dc79b31ad867e3fe93 100644 (file)
@@ -17,6 +17,9 @@
     Change History (most recent first):
 
 $Log: helper.c,v $
+Revision 1.24  2008/01/30 19:01:51  mcguire
+<rdar://problem/5703989> Crash in mDNSResponderHelper
+
 Revision 1.23  2007/11/30 23:21:51  cheshire
 Rename variables to eliminate "declaration of 'sin_loc' shadows a previous local" warning
 
@@ -139,14 +142,11 @@ debug_(const char *func, const char *fmt, ...)
        {
        char buf[2048];
        va_list ap;
-       ssize_t n = snprintf(buf, sizeof(buf), "%s: ", func);
 
-       if (n >= (int)sizeof(buf))
-               return;
        va_start(ap, fmt);
-       vsnprintf(&buf[n], sizeof(buf)-n, fmt, ap);
+       vsnprintf(buf, sizeof(buf), fmt, ap);
        va_end(ap);
-       helplog(ASL_LEVEL_DEBUG, buf);
+       helplog(ASL_LEVEL_DEBUG, "%s: %s", func, buf);
        }
 
 static int
index a1987412c20b3dfb54e7ac32b9b6a96e309a4566..6cfb6a47c01e7ae23b04c89071f26bc4de24d6ce 100644 (file)
     Change History (most recent first):
 
 $Log: mDNSMacOSX.c,v $
+Revision 1.536  2008/03/25 01:27:30  mcguire
+<rdar://problem/5810718> Status sometimes wrong when link goes down
+
+Revision 1.535  2008/03/14 22:52:51  mcguire
+<rdar://problem/5321824> write status to the DS
+Ignore duplicate queries, which don't get established (since they're duplicates)
+
+Revision 1.534  2008/03/12 22:58:15  mcguire
+<rdar://problem/5321824> write status to the DS
+Fixes for NO_SECURITYFRAMEWORK
+
+Revision 1.533  2008/03/07 00:48:54  mcguire
+<rdar://problem/5321824> write status to the DS
+cleanup strings
+
+Revision 1.532  2008/03/06 23:44:39  mcguire
+<rdar://problem/5321824> write status to the DS
+cleanup function names & log messages
+add external port numbers to dictionary
+add defensive code in case CF*Create fails
+don't output NAT statuses if zero
+
+Revision 1.531  2008/03/06 21:27:47  cheshire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+To save network bandwidth, removed unnecessary redundant information from HINFO record
+
+Revision 1.530  2008/03/06 03:15:48  mcguire
+<rdar://problem/5321824> write status to the DS
+use mStatus_* instead of kDNSServiceErr_*
+
+Revision 1.529  2008/03/06 02:48:35  mcguire
+<rdar://problem/5321824> write status to the DS
+
+Revision 1.528  2008/02/29 01:33:57  mcguire
+<rdar://problem/5611801> BTMM: Services stay registered after previously successful NAT Port mapping fails
+
+Revision 1.527  2008/02/28 03:25:26  mcguire
+<rdar://problem/5535772> config cleanup on shutdown/reboot
+
+Revision 1.526  2008/02/26 21:43:54  cheshire
+Renamed 'clockdivisor' to 'mDNSPlatformClockDivisor' (LogTimeStamps code needs to be able to access it)
+
+Revision 1.525  2008/02/20 00:53:20  cheshire
+<rdar://problem/5492035> getifaddrs is returning invalid netmask family for fw0 and vmnet
+Removed overly alarming syslog message
+
+Revision 1.524  2008/01/31 22:25:10  jgraessley
+<rdar://problem/5715434> using default Macintosh-0016CBF62EFD.local
+Use sysctlbyname to get hardware type for the default name.
+
+Revision 1.523  2008/01/15 01:32:56  jgraessley
+Bug #: 5595309
+Reviewed by: Stuart Cheshire
+Additional change to print warning message up to 1000 times to make it more visible
+
+Revision 1.522  2008/01/15 01:14:02  mcguire
+<rdar://problem/5674390> mDNSPlatformSendUDP should allow unicast queries on specific interfaces
+removed check and log message, as they are no longer relevant
+
 Revision 1.521  2007/12/14 00:58:28  cheshire
 <rdar://problem/5526800> BTMM: Need to deregister records and services on shutdown/sleep
 Additional fixes: When going to sleep, mDNSResponder needs to postpone sleep
@@ -778,8 +837,6 @@ Add (commented out) trigger value for testing "mach_absolute_time went backwards
 #pragma mark - Globals
 #endif
 
-static mDNSu32 clockdivisor = 0;
-
 mDNSexport int KQueueFD;
 
 #ifndef NO_SECURITYFRAMEWORK
@@ -966,13 +1023,6 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms
        int s = -1, err;
        mStatus result = mStatus_NoError;
 
-       // Sanity check: Make sure that if we're sending a query via unicast, we're sending it using our
-       // anonymous socket created for this purpose, so that we'll receive the response.
-       // If we use one of the many multicast sockets bound to port 5353 then we may not receive responses reliably.
-       if (InterfaceID && !mDNSAddrIsDNSMulticast(dst))
-               if ((((DNSMessage *)msg)->h.flags.b[0] & kDNSFlag0_QR_Mask) == kDNSFlag0_QR_Query)
-                       LogMsg("mDNSPlatformSendUDP: ERROR: Sending query OP from mDNS port to non-mDNS destination %#a:%d", dst, mDNSVal16(dstPort));
-
        if (dst->type == mDNSAddrType_IPv4)
                {
                struct sockaddr_in *sin_to = (struct sockaddr_in*)&to;
@@ -996,9 +1046,9 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms
                                #else
                                        {
                                        static int displayed = 0;
-                                       if (!displayed)
+                                       if (displayed < 1000)
                                                {
-                                               displayed = 1;
+                                               displayed++;
                                                LogOperation("IP_FORCE_OUT_IFP Socket option not defined -- cannot specify interface for unicast packets");
                                                }
                                        }
@@ -2127,6 +2177,230 @@ mDNSlocal NetworkInterfaceInfoOSX *FindRoutableIPv4(mDNS *const m, mDNSu32 scope
 
 static mDNSBool AnonymousRacoonConfig = mDNSfalse;
 
+#ifndef NO_SECURITYFRAMEWORK
+
+static CFMutableDictionaryRef domainStatusDict = NULL;
+
+// MUST be called with lock held
+mDNSlocal void RemoveAutoTunnelDomainStatus(const DomainAuthInfo *const info)
+       {
+       char buffer[1024];
+       CFStringRef domain;
+
+       LogOperation("RemoveAutoTunnelDomainStatus: %##s", info->domain.c);
+
+       if (!domainStatusDict) { LogMsg("RemoveAutoTunnelDomainStatus: No domainStatusDict"); return; }
+       
+       buffer[mDNS_snprintf(buffer, sizeof(buffer), "%##s", info->domain.c) - 1] = 0;
+       domain = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
+       if (!domain) { LogMsg("RemoveAutoTunnelDomainStatus: Could not create CFString domain"); return; }
+       
+       if (CFDictionaryContainsKey(domainStatusDict, domain))
+               {
+               CFDictionaryRemoveValue(domainStatusDict, domain);
+               mDNSDynamicStoreSetConfig(kmDNSBackToMyMacConfig, domainStatusDict);
+               }
+       CFRelease(domain);
+       }
+
+#endif // ndef NO_SECURITYFRAMEWORK
+
+// MUST be called with lock held
+mDNSlocal void UpdateAutoTunnelDomainStatus(const mDNS *const m, const DomainAuthInfo *const info)
+       {
+#ifdef NO_SECURITYFRAMEWORK
+       (void)m;
+       (void)info;
+#else
+       const NATTraversalInfo *const llq = m->LLQNAT.clientContext ? &m->LLQNAT : mDNSNULL;
+       const NATTraversalInfo *const tun = info->AutoTunnelNAT.clientContext ? &info->AutoTunnelNAT : mDNSNULL;
+       char buffer[1024];
+       CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       CFStringRef domain = NULL;
+       CFStringRef tmp = NULL;
+       CFNumberRef num = NULL;
+       mStatus status = mStatus_NoError;
+       
+       if (!domainStatusDict)
+               {
+               domainStatusDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+               if (!domainStatusDict) { LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFDictionary domainStatusDict"); return; }
+               }
+       
+       if (!dict) { LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFDictionary dict"); return; }
+
+       buffer[mDNS_snprintf(buffer, sizeof(buffer), "%##s", info->domain.c) - 1] = 0;
+       domain = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
+       if (!domain) { LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString domain"); return; }
+
+       mDNS_snprintf(buffer, sizeof(buffer), "%#a", &m->Router);
+       tmp = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
+       if (!tmp)
+               LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString RouterAddress");
+       else
+               {
+               CFDictionarySetValue(dict, CFSTR("RouterAddress"), tmp);
+               CFRelease(tmp);
+               }
+       
+       mDNS_snprintf(buffer, sizeof(buffer), "%.4a", &m->ExternalAddress);
+       tmp = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
+       if (!tmp)
+               LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString ExternalAddress");
+       else
+               {
+               CFDictionarySetValue(dict, CFSTR("ExternalAddress"), tmp);
+               CFRelease(tmp);
+               }
+       
+       if (llq)
+               {
+               mDNSu32 port = mDNSVal16(llq->ExternalPort);
+               
+               num = CFNumberCreate(NULL, kCFNumberSInt32Type, &port);
+               if (!num)
+                       LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber LLQExternalPort");
+               else
+                       {
+                       CFDictionarySetValue(dict, CFSTR("LLQExternalPort"), num);
+                       CFRelease(num);
+                       }
+
+               if (llq->Result)
+                       {
+                       num = CFNumberCreate(NULL, kCFNumberSInt32Type, &llq->Result);
+                       if (!num)
+                               LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber LLQNPMStatus");
+                       else
+                               {
+                               CFDictionarySetValue(dict, CFSTR("LLQNPMStatus"), num);
+                               CFRelease(num);
+                               }
+                       }
+               }
+       
+       if (tun)
+               {
+               mDNSu32 port = mDNSVal16(tun->ExternalPort);
+               
+               num = CFNumberCreate(NULL, kCFNumberSInt32Type, &port);
+               if (!num)
+                       LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber AutoTunnelExternalPort");
+               else
+                       {
+                       CFDictionarySetValue(dict, CFSTR("AutoTunnelExternalPort"), num);
+                       CFRelease(num);
+                       }
+
+               if (tun->Result)
+                       {
+                       num = CFNumberCreate(NULL, kCFNumberSInt32Type, &tun->Result);
+                       if (!num)
+                               LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber AutoTunnelNPMStatus");
+                       else
+                               {
+                               CFDictionarySetValue(dict, CFSTR("AutoTunnelNPMStatus"), num);
+                               CFRelease(num);
+                               }
+                       }
+               }
+       
+       if (!llq && !tun)
+               {
+               status = mStatus_NotInitializedErr;
+               mDNS_snprintf(buffer, sizeof(buffer), "Neither LLQ nor AutoTunnel NAT port mapping is currently active");
+               }       
+       else if ((llq && llq->Result == mStatus_DoubleNAT) || (tun && tun->Result == mStatus_DoubleNAT))
+               {
+               status = mStatus_DoubleNAT;
+               mDNS_snprintf(buffer, sizeof(buffer), "Double NAT: Router is reporting an external address");
+               }
+       else if ((llq && llq->Result) || (tun && tun->Result))
+               {
+               status = mStatus_NATTraversal;
+               mDNS_snprintf(buffer, sizeof(buffer), "Error obtaining NAT port mapping from router");
+               }
+       else if (m->Router.type == mDNSAddrType_None)
+               {
+               status = mStatus_NoRouter;
+               mDNS_snprintf(buffer, sizeof(buffer), "No network connection - none");
+               }
+       else if (m->Router.type == mDNSAddrType_IPv4 && mDNSIPv4AddressIsZero(m->Router.ip.v4))
+               {
+               status = mStatus_NoRouter;
+               mDNS_snprintf(buffer, sizeof(buffer), "No network connection - v4 zero");
+               }
+       else if ((llq && mDNSIPPortIsZero(llq->ExternalPort)) || (tun && mDNSIPPortIsZero(tun->ExternalPort)))
+               {
+               status = mStatus_NATTraversal;
+               mDNS_snprintf(buffer, sizeof(buffer), "Unable to obtain NAT port mapping from router");
+               }
+       else
+               {
+               DNSQuestion* q;
+               for (q = m->Questions; q; q=q->next)
+                       if (q->LongLived && q->AuthInfo == info && q->state == LLQ_Poll)
+                               {
+                               status = mStatus_PollingMode;
+                               mDNS_snprintf(buffer, sizeof(buffer), "Query polling %##s", q->qname.c);
+                               break;
+                               }
+               if (status == mStatus_NoError)
+                       for (q = m->Questions; q; q=q->next)
+                               if (q->LongLived && q->AuthInfo == info && q->state != LLQ_Established && !q->DuplicateOf)
+                                       {
+                                       status = mStatus_TransientErr;
+                                       mDNS_snprintf(buffer, sizeof(buffer), "Query not yet established %##s", q->qname.c);
+                                       break;
+                                       }
+               if (status == mStatus_NoError) mDNS_snprintf(buffer, sizeof(buffer), "Success");
+               }
+       
+       num = CFNumberCreate(NULL, kCFNumberSInt32Type, &status);
+       if (!num)
+               LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber StatusCode");
+       else
+               {
+               CFDictionarySetValue(dict, CFSTR("StatusCode"), num);
+               CFRelease(num);
+               }
+               
+       tmp = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
+       if (!tmp)
+               LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString StatusMessage");
+       else
+               {
+               CFDictionarySetValue(dict, CFSTR("StatusMessage"), tmp);
+               CFRelease(tmp);
+               }
+
+       if (!CFDictionaryContainsKey(domainStatusDict, domain) ||
+           !CFEqual(dict, (CFMutableDictionaryRef)CFDictionaryGetValue(domainStatusDict, domain)))
+           {
+               CFDictionarySetValue(domainStatusDict, domain, dict);
+               mDNSDynamicStoreSetConfig(kmDNSBackToMyMacConfig, domainStatusDict);
+               }
+               
+       CFRelease(domain);
+       CFRelease(dict);
+
+       LogOperation("UpdateAutoTunnelDomainStatus: %s", buffer);
+#endif // def NO_SECURITYFRAMEWORK
+       }
+
+// MUST be called with lock held
+mDNSexport void UpdateAutoTunnelDomainStatuses(const mDNS *const m)
+       {
+#ifdef NO_SECURITYFRAMEWORK
+       (void)m;
+#else
+       DomainAuthInfo* info;
+       for (info = m->AuthInfoList; info; info = info->next)
+               if (info->AutoTunnel && !info->deltime)
+                       UpdateAutoTunnelDomainStatus(m, info);
+#endif // def NO_SECURITYFRAMEWORK
+       }
+       
 // MUST be called with lock held
 mDNSlocal mDNSBool TunnelServers(mDNS *const m)
        {
@@ -2250,6 +2524,12 @@ mDNSlocal void AutoTunnelRecordCallback(mDNS *const m, AuthRecord *const rr, mSt
        if (result == mStatus_MemFree)
                {
                LogOperation("AutoTunnelRecordCallback MemFree %s", ARDisplayString(m, rr));
+               // Reset the host record namestorage to force high-level PTR/SRV/TXT to deregister
+               if (rr == &info->AutoTunnelHostRecord)
+                       {
+                       rr->namestorage.c[0] = 0;
+                       m->NextSRVUpdate = NonZeroTime(m->timenow);
+                       }
                RegisterAutoTunnelRecords(m,info);
                }
        }
@@ -2275,6 +2555,8 @@ mDNSlocal void AutoTunnelNATCallback(mDNS *m, NATTraversalInfo *n)
                // Create or revert configuration file, and start (or SIGHUP) Racoon
                (void)mDNSConfigureServer(AnonymousRacoonConfig ? kmDNSUp : kmDNSDown, info ? info->b64keydata : "");
                }
+               
+       UpdateAutoTunnelDomainStatus(m, (DomainAuthInfo *)n->clientContext);
        }
 
 mDNSlocal void AbortDeregistration(mDNS *const m, AuthRecord *rr)
@@ -2522,6 +2804,32 @@ mDNSexport void AddNewClientTunnel(mDNS *const m, DNSQuestion *const q)
 #pragma mark - Power State & Configuration Change Management
 #endif
 
+mDNSlocal void GenerateDefaultName(const mDNSEthAddr PrimaryMAC, char *buffer, mDNSu32 length)
+{
+       char    hwName[32];
+       size_t  hwNameLen = sizeof(hwName);
+       
+       hwName[0] = 0;
+       if (sysctlbyname("hw.model", &hwName, &hwNameLen, NULL, 0) == 0)
+               {
+               // hw.model contains a number like iMac6,1. We want the "iMac" part.
+               hwName[sizeof(hwName) - 1] = 0;
+               char    *ptr;
+               for (ptr = hwName; *ptr != 0; ptr++)
+                       {
+                       if (*ptr >= '0' && *ptr <= '9') *ptr = 0;
+                       if (*ptr == ',') break;
+                       }
+               // Prototype model names do not contain commas, do not use prototype names
+               if (*ptr != ',') hwName[0] = 0;
+               }
+       
+       if (hwName[0] == 0) strlcpy(hwName, "Device", sizeof(hwName));
+       
+       mDNS_snprintf(buffer, length, "%s-%02X%02X%02X%02X%02X%02X", hwName,
+               PrimaryMAC.b[0], PrimaryMAC.b[1], PrimaryMAC.b[2], PrimaryMAC.b[3], PrimaryMAC.b[4], PrimaryMAC.b[5]);
+}
+
 mDNSlocal mStatus UpdateInterfaceList(mDNS *const m, mDNSs32 utc)
        {
        mDNSBool foundav4           = mDNSfalse;
@@ -2530,7 +2838,7 @@ mDNSlocal mStatus UpdateInterfaceList(mDNS *const m, mDNSs32 utc)
        struct ifaddrs *v4Loopback  = NULL;
        struct ifaddrs *v6Loopback  = NULL;
        mDNSEthAddr PrimaryMAC      = zeroEthAddr;
-       char defaultname[32];
+       char defaultname[64];
 #ifndef NO_IPV6
        int InfoSocket              = socket(AF_INET6, SOCK_DGRAM, 0);
        if (InfoSocket < 3 && errno != EAFNOSUPPORT) LogMsg("UpdateInterfaceList: InfoSocket error %d errno %d (%s)", InfoSocket, errno, strerror(errno));
@@ -2580,7 +2888,9 @@ mDNSlocal mStatus UpdateInterfaceList(mDNS *const m, mDNSs32 utc)
                                        LogMsg("getifaddrs: ifa_netmask is NULL for %5s(%d) Flags %04X Family %2d %#a",
                                                ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family, &ip);
                                        }
-                               else if (ifa->ifa_addr->sa_family != ifa->ifa_netmask->sa_family)
+                               // Apparently it's normal for the sa_family of an ifa_netmask to sometimes be zero, so we don't complain about that
+                               // <rdar://problem/5492035> getifaddrs is returning invalid netmask family for fw0 and vmnet
+                               else if (ifa->ifa_netmask->sa_family != ifa->ifa_addr->sa_family && ifa->ifa_netmask->sa_family != 0)
                                        {
                                        mDNSAddr ip;
                                        SetupAddr(&ip, ifa->ifa_addr);
@@ -2589,6 +2899,9 @@ mDNSlocal mStatus UpdateInterfaceList(mDNS *const m, mDNSs32 utc)
                                        }
                                else
                                        {
+                                       // Make sure ifa_netmask->sa_family is set correctly
+                                       // <rdar://problem/5492035> getifaddrs is returning invalid netmask family for fw0 and vmnet
+                                       ifa->ifa_netmask->sa_family = ifa->ifa_addr->sa_family;
                                        int ifru_flags6 = 0;
 #ifndef NO_IPV6
                                        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
@@ -2675,12 +2988,8 @@ mDNSlocal mStatus UpdateInterfaceList(mDNS *const m, mDNSs32 utc)
                        m->AutoTunnelHostAddr.b[0xC], m->AutoTunnelHostAddr.b[0xD], m->AutoTunnelHostAddr.b[0xE], m->AutoTunnelHostAddr.b[0xF]);
                LogOperation("m->AutoTunnelLabel %#s", m->AutoTunnelLabel.c);
                }
-
-       #ifndef kDefaultLocalHostNamePrefix
-       #define kDefaultLocalHostNamePrefix "Macintosh"
-       #endif
-       mDNS_snprintf(defaultname, sizeof(defaultname), kDefaultLocalHostNamePrefix "-%02X%02X%02X%02X%02X%02X",
-               PrimaryMAC.b[0], PrimaryMAC.b[1], PrimaryMAC.b[2], PrimaryMAC.b[3], PrimaryMAC.b[4], PrimaryMAC.b[5]);
+       
+       GenerateDefaultName(PrimaryMAC, defaultname, sizeof(defaultname));
 
        // Set up the nice label
        domainlabel nicelabel;
@@ -2977,9 +3286,12 @@ mDNSexport void mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDN
                                ifa->ifa_netmask                    &&
                                !(ifa->ifa_flags & IFF_LOOPBACK)        &&
                                !SetupAddr(&a, ifa->ifa_addr)           &&
-                               !SetupAddr(&n, ifa->ifa_netmask)        &&
                                !mDNSv4AddressIsLinkLocal(&a.ip.v4)  )
                                {
+                               // Apparently it's normal for the sa_family of an ifa_netmask to sometimes be incorrect, so we explicitly fix it here before calling SetupAddr
+                               // <rdar://problem/5492035> getifaddrs is returning invalid netmask family for fw0 and vmnet
+                               ifa->ifa_netmask->sa_family = ifa->ifa_addr->sa_family;         // Make sure ifa_netmask->sa_family is set correctly
+                               SetupAddr(&n, ifa->ifa_netmask);
                                // Note: This is reverse order compared to a normal dotted-decimal IP address, so we can't use our customary "%.4a" format code
                                mDNS_snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa.", a.ip.v4.b[3] & n.ip.v4.b[3],
                                                                                                                                                         a.ip.v4.b[2] & n.ip.v4.b[2],
@@ -3546,6 +3858,8 @@ mDNSexport void SetDomainSecrets(mDNS *m)
                                LogOperation("SetDomainSecrets: secret changed for %##s", &domain);
                                (void)mDNSConfigureServer(kmDNSUp, stringbuf);
                                }
+                               
+                       if (ptr->AutoTunnel) UpdateAutoTunnelDomainStatus(m, ptr);
 #endif APPLE_OSX_mDNSResponder
 
                        ConvertDomainNameToCString(&domain, stringbuf);
@@ -3579,22 +3893,26 @@ mDNSexport void SetDomainSecrets(mDNS *m)
                DomainAuthInfo *info = m->AuthInfoList;
                while (info)
                        {
-                       if (info->AutoTunnel && info->deltime && info->AutoTunnelNAT.clientContext)
+                       if (info->AutoTunnel && info->deltime)
                                {
-                               // stop the NAT operation
-                               mDNS_StopNATOperation_internal(m, &info->AutoTunnelNAT);
-                               if (info->AutoTunnelNAT.clientCallback)
+                               if (info->AutoTunnelNAT.clientContext)
                                        {
-                                       // Reset port and let the AutoTunnelNATCallback handle cleanup
-                                       info->AutoTunnelNAT.ExternalAddress = m->ExternalAddress;
-                                       info->AutoTunnelNAT.ExternalPort    = zeroIPPort;
-                                       info->AutoTunnelNAT.Lifetime        = 0;
-                                       info->AutoTunnelNAT.Result          = mStatus_NoError;
-                                       mDNS_DropLockBeforeCallback(); // Allow client to legally make mDNS API calls from the callback
-                                       info->AutoTunnelNAT.clientCallback(m, &info->AutoTunnelNAT);
-                                       mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
+                                       // stop the NAT operation
+                                       mDNS_StopNATOperation_internal(m, &info->AutoTunnelNAT);
+                                       if (info->AutoTunnelNAT.clientCallback)
+                                               {
+                                               // Reset port and let the AutoTunnelNATCallback handle cleanup
+                                               info->AutoTunnelNAT.ExternalAddress = m->ExternalAddress;
+                                               info->AutoTunnelNAT.ExternalPort    = zeroIPPort;
+                                               info->AutoTunnelNAT.Lifetime        = 0;
+                                               info->AutoTunnelNAT.Result          = mStatus_NoError;
+                                               mDNS_DropLockBeforeCallback(); // Allow client to legally make mDNS API calls from the callback
+                                               info->AutoTunnelNAT.clientCallback(m, &info->AutoTunnelNAT);
+                                               mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
+                                               }
+                                       info->AutoTunnelNAT.clientContext = mDNSNULL;
                                        }
-                               info->AutoTunnelNAT.clientContext = mDNSNULL;
+                               RemoveAutoTunnelDomainStatus(info);
                                }
                        info = info->next;
                        }
@@ -3916,7 +4234,7 @@ mDNSexport int mDNSMacOSXSystemBuildNumber(char *HINFO_SWstring)
                CFRelease(vers);
                }
        if (!major) { major=8; LogMsg("Note: No Major Build Version number found; assuming 8"); }
-       if (HINFO_SWstring) mDNS_snprintf(HINFO_SWstring, 256, "%s %s (%s), %s", prodname, prodvers, buildver, mDNSResponderVersionString);
+       if (HINFO_SWstring) mDNS_snprintf(HINFO_SWstring, 256, "%s %s (%s), %s", prodname, prodvers, buildver, STRINGIFY(mDNSResponderVersion));
        return(major);
        }
 
@@ -4111,10 +4429,28 @@ mDNSexport void mDNSPlatformClose(mDNS *const m)
        CloseSocketSet(&m->p->permanentsockets);
 
        #if APPLE_OSX_mDNSResponder
+       // clean up tunnels
+       while (m->TunnelClients)
+               {
+               ClientTunnel *cur = m->TunnelClients;
+               LogOperation("mDNSPlatformClose: removing client tunnel %p %##s from list", cur, cur->dstname.c);
+               if (cur->q.ThisQInterval >= 0) mDNS_StopQuery(m, &cur->q);
+               AutoTunnelSetKeys(cur, mDNSfalse);
+               m->TunnelClients = cur->next;
+               freeL("ClientTunnel", cur);
+               }
+
+       if (AnonymousRacoonConfig)
+               {
+               AnonymousRacoonConfig = mDNSfalse;
+               LogOperation("mDNSPlatformClose: Deconfiguring autotunnel");
+               (void)mDNSConfigureServer(kmDNSDown, "");
+               }
+
        if (m->AutoTunnelHostAddrActive && m->AutoTunnelHostAddr.b[0])
                {
                m->AutoTunnelHostAddrActive = mDNSfalse;
-               LogMsg("Removing AutoTunnel address %.16a", &m->AutoTunnelHostAddr);
+               LogOperation("mDNSPlatformClose: Removing AutoTunnel address %.16a", &m->AutoTunnelHostAddr);
                (void)mDNSAutoTunnelInterfaceUpDown(kmDNSDown, m->AutoTunnelHostAddr.b);
                }
        #endif // APPLE_OSX_mDNSResponder
@@ -4131,6 +4467,7 @@ mDNSexport mDNSu32 mDNSPlatformRandomSeed(void)
        }
 
 mDNSexport mDNSs32 mDNSPlatformOneSecond = 1000;
+mDNSexport mDNSu32 mDNSPlatformClockDivisor = 0;
 
 mDNSexport mStatus mDNSPlatformTimeInit(void)
        {
@@ -4154,13 +4491,13 @@ mDNSexport mStatus mDNSPlatformTimeInit(void)
        // When we ship Macs with clock frequencies above 1000GHz, we may have to update this code.
        struct mach_timebase_info tbi;
        kern_return_t result = mach_timebase_info(&tbi);
-       if (result == KERN_SUCCESS) clockdivisor = ((uint64_t)tbi.denom * 1000000) / tbi.numer;
+       if (result == KERN_SUCCESS) mDNSPlatformClockDivisor = ((uint64_t)tbi.denom * 1000000) / tbi.numer;
        return(result);
        }
 
 mDNSexport mDNSs32 mDNSPlatformRawTime(void)
        {
-       if (clockdivisor == 0) { LogMsg("mDNSPlatformRawTime called before mDNSPlatformTimeInit"); return(0); }
+       if (mDNSPlatformClockDivisor == 0) { LogMsg("mDNSPlatformRawTime called before mDNSPlatformTimeInit"); return(0); }
 
        static uint64_t last_mach_absolute_time = 0;
        //static uint64_t last_mach_absolute_time = 0x8000000000000000LL;       // Use this value for testing the alert display
@@ -4182,7 +4519,7 @@ mDNSexport mDNSs32 mDNSPlatformRawTime(void)
                }
        last_mach_absolute_time = this_mach_absolute_time;
 
-       return((mDNSs32)(this_mach_absolute_time / clockdivisor));
+       return((mDNSs32)(this_mach_absolute_time / mDNSPlatformClockDivisor));
        }
 
 mDNSexport mDNSs32 mDNSPlatformUTC(void)
index 97ba7e100447cacf57fc18cbcc0e85ae47a5df74..b0307f910ce8fd08d0dbb24fbb02f7b6f79feea3 100644 (file)
@@ -26,6 +26,9 @@
 ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ;
 ; $Log: mDNSResponder.sb,v $
+; Revision 1.25  2008/03/17 18:04:41  mcguire
+; <rdar://problem/5800476> SC now reads preference file
+;
 ; Revision 1.24  2007/09/20 22:33:17  cheshire
 ; Tidied up inconsistent and error-prone naming -- used to be mDNSResponderHelper in
 ; some places and mDNSResponder.helper in others; now mDNSResponderHelper everywhere
 (allow file-read-data                 (regex "^/usr/share/icu/.*\$"))
 (allow file-read-data                 (regex "^/usr/share/zoneinfo/.*\$"))
 (allow file-read-data                 (regex "^/System/Library/CoreServices/SystemVersion.*\$"))
+(allow file-read-data                 (regex "^/Library/Preferences/SystemConfiguration/preferences\.plist\$"))
 (allow file-read-data                 (regex "^/Library/Preferences/(ByHost/)?\.GlobalPreferences.*\.plist\$"))
 (allow file-read-data                 (regex "^/Library/Preferences/com\.apple\.security.*\.plist\$"))
 (allow file-read-data                 (regex "^/Library/Preferences/com\.apple\.crypto\.plist\$"))
index 904efc0e6e29de639eacf999b8726620460a314e..df36500ad4071ac5c9f5fb5367a1713f038f65ad 100644 (file)
                                GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                HEADER_SEARCH_PATHS = (
                                        ../mDNSShared,
+                                       "${SYSTEM_LIBRARY_DIR}/Frameworks/System.framework/PrivateHeaders",
                                        "${APPLE_INTERNAL_DEVELOPER_DIR}/Headers",
                                        "${CONFIGURATION_TEMP_DIR}",
                                );
                                );
                                HEADER_SEARCH_PATHS = (
                                        ../mDNSShared,
+                                       "${SYSTEM_LIBRARY_DIR}/Frameworks/System.framework/PrivateHeaders",
                                        "${APPLE_INTERNAL_DEVELOPER_DIR}/Headers",
                                        "${CONFIGURATION_TEMP_DIR}",
                                );
                                GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                HEADER_SEARCH_PATHS = ../mDNSShared;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.3;
+                               MACOSX_DEPLOYMENT_TARGET = 10.4;
                                OTHER_CFLAGS = "-no-cpp-precomp";
                                OTHER_LDFLAGS = "";
                                OTHER_REZFLAGS = "";
index 61c53614b00b8c2b362f96499720a9585046c63b..434c2f1a5b684cbb3833fd832a99341d1950b78b 100644 (file)
     Change History (most recent first):
 
 $Log: PlatformCommon.c,v $
+Revision 1.17  2008/03/05 00:19:09  cheshire
+Conditionalize LogTimeStamps so it's specific to APPLE_OSX, for now
+
+Revision 1.16  2008/02/26 21:47:45  cheshire
+Added cast to avoid compiler warning
+
+Revision 1.15  2008/02/26 21:42:26  cheshire
+Added 'LogTimeStamps' option, to show ms-granularity timestamps on every log message
+
 Revision 1.14  2007/12/03 18:37:26  cheshire
 Moved mDNSPlatformWriteLogMsg & mDNSPlatformWriteDebugMsg
 from mDNSMacOSX.c to PlatformCommon.c, so that Posix build can use them
@@ -160,7 +169,7 @@ mDNSexport void ReadDDNSSettingsFromConfFile(mDNS *const m, const char *const fi
                if (hostname && GetConfigOption(buf, "hostname", f) && !MakeDomainNameFromDNSNameString(hostname, buf)) goto badf;
                if (domain && GetConfigOption(buf, "zone", f) && !MakeDomainNameFromDNSNameString(domain, buf)) goto badf;
                buf[0] = 0;
-               GetConfigOption(buf, "secret-64", f);  // failure means no authentication                       
+               GetConfigOption(buf, "secret-64", f);  // failure means no authentication
                fclose(f);
                f = NULL;
                }
@@ -182,28 +191,45 @@ mDNSexport void ReadDDNSSettingsFromConfFile(mDNS *const m, const char *const fi
 
        badf:
        LogMsg("ERROR: malformatted config file");
-       if (f) fclose(f);       
+       if (f) fclose(f);
        }
 
 #if MDNS_DEBUGMSGS
-mDNSexport void        mDNSPlatformWriteDebugMsg(const char *msg)
+mDNSexport void mDNSPlatformWriteDebugMsg(const char *msg)
        {
        fprintf(stderr,"%s\n", msg);
        fflush(stderr);
        }
 #endif
 
-mDNSexport void        mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, int logoptflags)
+mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, int logoptflags)
        {
+#if APPLE_OSX_mDNSResponder && LogTimeStamps
+       extern mDNS mDNSStorage;
+       extern mDNSu32 mDNSPlatformClockDivisor;
+       mDNSs32 t = mDNSStorage.timenow ? mDNSStorage.timenow : mDNSPlatformClockDivisor ? mDNS_TimeNow_NoLock(&mDNSStorage) : 0;
+       int ms = ((t < 0) ? -t : t) % 1000;
+#endif
+
        if (mDNS_DebugMode)     // In debug mode we write to stderr
                {
-               fprintf(stderr,"%s\n", buffer);
+#if APPLE_OSX_mDNSResponder && LogTimeStamps
+               if (mDNSPlatformClockDivisor)
+                       fprintf(stderr,"%8d.%03d: %s\n", (int)(t/1000), ms, buffer);
+               else
+#endif
+                       fprintf(stderr,"%s\n", buffer);
                fflush(stderr);
                }
        else                            // else, in production mode, we write to syslog
                {
                openlog(ident, LOG_CONS | logoptflags, LOG_DAEMON);
-               syslog(LOG_ERR, "%s", buffer);
+#if APPLE_OSX_mDNSResponder && LogTimeStamps
+               if (mDNSPlatformClockDivisor)
+                       syslog(LOG_ERR, "%8d.%03d: %s", (int)(t/1000), ms, buffer);
+               else
+#endif
+                       syslog(LOG_ERR, "%s", buffer);
                closelog();
                }
        }
index da571b2a5845265449e5a57c6a04ed82bbeae6c8..cc4169b3995f799d2245d13911707dea4aa343f1 100644 (file)
@@ -77,7 +77,7 @@
  */
 
 #ifndef _DNS_SD_H
-#define _DNS_SD_H 1700000
+#define _DNS_SD_H 1710400
 
 #ifdef  __cplusplus
     extern "C" {
@@ -443,8 +443,10 @@ enum
     kDNSServiceErr_BadKey                    = -65561,
     kDNSServiceErr_Transient                 = -65562,
     kDNSServiceErr_ServiceNotRunning         = -65563,  /* Background daemon not running */
-    kDNSServiceErr_NATPortMappingUnsupported = -65564,  /* No NAT or if the NAT doesn't support NAT-PMP or UPnP. */
-    kDNSServiceErr_NATPortMappingDisabled    = -65565   /* NAT supports NAT-PMP or UPnP but it's disabled by the administrator */
+    kDNSServiceErr_NATPortMappingUnsupported = -65564,  /* NAT doesn't support NAT-PMP or UPnP */
+    kDNSServiceErr_NATPortMappingDisabled    = -65565,  /* NAT supports NAT-PMP or UPnP but it's disabled by the administrator */
+    kDNSServiceErr_NoRouter                  = -65566,  /* No router currently configured (probably no network connectivity) */
+    kDNSServiceErr_PollingMode               = -65567
 
     /* mDNS Error codes are in the range
      * FFFE FF00 (-65792) to FFFE FFFF (-65537) */
@@ -1729,9 +1731,11 @@ DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
  *
  * interfaceIndex:  The interface through which the NAT gateway is reached.
  *
- * errorCode:       Will be kDNSServiceErr_NoError on success, otherwise will
- *                  indicate the failure that occurred. Other parameters are
- *                  undefined if errorCode is nonzero.
+ * errorCode:       Will be kDNSServiceErr_NoError on success.
+ *                  Will be kDNSServiceErr_DoubleNAT when the NAT gateway is itself behind one or
+ *                  more layers of NAT, in which case the other parameters have the defined values.
+ *                  For other failures, will indicate the failure that occurred, and the other
+ *                  parameters are undefined.
  *
  * publicAddress:   Four byte IPv4 address in network byte order.
  *
index 5a6541cf67d3c615f3da6928f7da24eca705bf29..807ced9fcaeba35f66fbd843216a39613ed3edba 100644 (file)
@@ -17,6 +17,9 @@
     Change History (most recent first):
 
 $Log: dnsextd.c,v $
+Revision 1.88  2008/03/06 21:26:11  cheshire
+Moved duplicated STRINGIFY macro from individual C files to DNSCommon.h
+
 Revision 1.87  2007/12/17 23:34:50  cheshire
 Don't need to set ptr to result of DNSDigest_SignMessage -- ptr is updated anyway (it's passed by reference)
 
@@ -3255,12 +3258,6 @@ mStatus mDNS_StopQuery(mDNS *const m, DNSQuestion *const question) { ( void ) m;
 mDNS mDNSStorage;
 
 
-// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
-// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
-// To expand "version" to its value before making the string, use STRINGIFY(version) instead
-#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) #s
-#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
-
 // For convenience when using the "strings" command, this is the last thing in the file
 // The "@(#) " pattern is a special prefix the "what" command looks for
 const char mDNSResponderVersionString_SCCS[] = "@(#) dnsextd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
index d197344ce868ba98a07d9921b6fe3c9159202d86..3aac7eda9ce460f4a096d9201b6e7ba34e79b958 100644 (file)
        Change History (most recent first):
 
 $Log: dnssd_clientstub.c,v $
+Revision 1.102  2008/02/25 19:16:19  cheshire
+<rdar://problem/5708953> Problems with DNSServiceGetAddrInfo API
+Was returning a bogus result (NULL pointer) when following a CNAME referral
+
+Revision 1.101  2008/02/20 21:18:21  cheshire
+<rdar://problem/5708953> DNSServiceGetAddrInfo doesn't set the scope ID of returned IPv6 link local addresses
+
 Revision 1.100  2007/11/02 17:56:37  cheshire
 <rdar://problem/5565787> Bonjour API broken for 64-bit apps (SCM_RIGHTS sendmsg fails)
 Wrap hack code in "#if APPLE_OSX_mDNSResponder" since (as far as we know right now)
@@ -1081,43 +1088,53 @@ DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
 
 static void handle_addrinfo_response(DNSServiceOp *sdr, CallbackHeader *cbh, char *data, char *end)
        {
-       uint32_t ttl;
        char hostname[kDNSServiceMaxDomainName];
        uint16_t rrtype, rrclass, rdlen;
        char *rdata;
-       struct sockaddr_in  sa4;
-       struct sockaddr_in6 sa6;
-       struct sockaddr   * sa = NULL;
+       uint32_t ttl;
 
        get_string(&data, end, hostname, kDNSServiceMaxDomainName);
        rrtype  = get_uint16(&data, end);
        rrclass = get_uint16(&data, end);
        rdlen   = get_uint16(&data, end);
-       rdata   = get_rdata(&data, end, rdlen);
+       rdata   = get_rdata (&data, end, rdlen);
        ttl     = get_uint32(&data, end);
-       
+
+       // We only generate client callbacks for A and AAAA results (including NXDOMAIN results for
+       // those types, if the client has requested those with the kDNSServiceFlagsReturnIntermediates).
+       // Other result types, specifically CNAME referrals, are not communicated to the client, because
+       // the DNSServiceGetAddrInfoReply interface doesn't have any meaningful way to communiate CNAME referrals.
        if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_addrinfo_response: error reading result from daemon");
-       else
+       else if (rrtype == kDNSServiceType_A || rrtype == kDNSServiceType_AAAA)
                {
+               struct sockaddr_in  sa4;
+               struct sockaddr_in6 sa6;
+               const struct sockaddr *const sa = (rrtype == kDNSServiceType_A) ? (struct sockaddr*)&sa4 : (struct sockaddr*)&sa6;
                if (rrtype == kDNSServiceType_A)
                        {
-                       sa = (struct sockaddr *)&sa4;
                        bzero(&sa4, sizeof(sa4));
                        #ifndef NOT_HAVE_SA_LEN
-                       sa->sa_len = sizeof(struct sockaddr_in);
+                       sa4.sin_len = sizeof(struct sockaddr_in);
                        #endif
-                       sa->sa_family = AF_INET;
+                       sa4.sin_family = AF_INET;
+                       //  sin_port   = 0;
                        if (!cbh->cb_err) memcpy(&sa4.sin_addr, rdata, rdlen);
                        }
-               else if (rrtype == kDNSServiceType_AAAA)
+               else
                        {
-                       sa = (struct sockaddr *)&sa6;
                        bzero(&sa6, sizeof(sa6));
                        #ifndef NOT_HAVE_SA_LEN
-                       sa->sa_len = sizeof(struct sockaddr_in6);
+                       sa6.sin6_len = sizeof(struct sockaddr_in6);
                        #endif
-                       sa->sa_family = AF_INET6;
-                       if (!cbh->cb_err) memcpy(&sa6.sin6_addr, rdata, rdlen);
+                       sa6.sin6_family     = AF_INET6;
+                       //  sin6_port     = 0;
+                       //  sin6_flowinfo = 0;
+                       //  sin6_scope_id = 0;
+                       if (!cbh->cb_err)
+                               {
+                               memcpy(&sa6.sin6_addr, rdata, rdlen);
+                               if (IN6_IS_ADDR_LINKLOCAL(&sa6.sin6_addr)) sa6.sin6_scope_id = cbh->cb_interface;
+                               }
                        }
                ((DNSServiceGetAddrInfoReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, hostname, sa, ttl, sdr->AppContext);
                // MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
index 3e0a60196f8c9007a2dd1130fc99ab188716a41f..a01eb085727093790aa79ff5e63d4948f3300265 100644 (file)
        Change History (most recent first):
 
 $Log: uds_daemon.c,v $
+Revision 1.387  2008/02/26 21:24:13  cheshire
+Fixed spelling mistake in comment
+
+Revision 1.386  2008/02/26 20:23:15  cheshire
+Updated comments
+
+Revision 1.385  2008/02/19 21:50:52  cheshire
+Shortened some overly-long lines
+
 Revision 1.384  2007/12/22 01:38:05  cheshire
 Improve display of "Auth Records" SIGINFO output
 
@@ -722,7 +731,7 @@ typedef struct registered_record_entry
        {
        struct registered_record_entry *next;
        mDNSu32 key;
-       AuthRecord *rr;         // Variable-sized AuthRecord
+       AuthRecord *rr;                         // Pointer to variable-sized AuthRecord
        client_context_t client_context;
        request_state *request;
        } registered_record_entry;
@@ -740,7 +749,7 @@ typedef struct service_instance
     mDNSBool clientnotified;           // Has client been notified of successful registration yet?
        mDNSBool default_local;                 // is this the "local." from an empty-string registration?
        domainname domain;
-       ServiceRecordSet srs;                   // note - must be last field in struct
+       ServiceRecordSet srs;                   // note -- variable-sized object -- must be last field in struct
        } service_instance;
 
 // for multi-domain default browsing
@@ -766,7 +775,7 @@ struct request_state
        transfer_state ts;
        mDNSu32 hdr_bytes;                              // bytes of header already read
        ipc_msg_hdr hdr;
-       mDNSu32 data_bytes;                     // bytes of message data already read
+       mDNSu32 data_bytes;                             // bytes of message data already read
        char *msgbuf;                                   // pointer to data storage to pass to free()
        char *msgptr;                                   // pointer to data to be read from (may be modified)
        char *msgend;                                   // pointer to byte after last byte of message
@@ -1709,7 +1718,8 @@ mDNSlocal mStatus register_service_instance(request_state *request, const domain
                        { LogMsg("register_service_instance: domain %##s already registered", domain->c); return mStatus_AlreadyRegistered; }
                }
 
-       // Special-case hack: We don't advertise SMB service in AutoTunnel domains, because AutoTunnel services have to support IPv6, and our SMB server does not
+       // Special-case hack: We don't advertise SMB service in AutoTunnel domains, because AutoTunnel
+       // services have to support IPv6, and our SMB server does not
        // <rdar://problem/5482322> BTMM: Don't advertise SMB with BTMM because it doesn't support IPv6
        if (SameDomainName(&request->u.servicereg.type, (const domainname *) "\x4" "_smb" "\x4" "_tcp"))
                {
@@ -2545,11 +2555,6 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
 // to the mDNSCore routine) that sends results back to the client, and a termination routine that aborts
 // the mDNSCore operation if the client dies or closes its socket.
 
-// query and resolve calls have separate request handlers that parse the arguments from the client and
-// massage the name parameters appropriately, but the rest of the operations (making the query call,
-// delivering the result to the client, and termination) are identical.
-
-// what gets called when a resolve is completed and we need to send the data back to the client
 mDNSlocal void queryrecord_result_callback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
        {
        char name[MAX_ESCAPED_DOMAIN_NAME];
@@ -2636,7 +2641,8 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
        rrtype  = get_uint16(&request->msgptr, request->msgend);
        rrclass = get_uint16(&request->msgptr, request->msgend);
 
-       if (!request->msgptr) { LogMsg("%3d: DNSServiceQueryRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
+       if (!request->msgptr)
+               { LogMsg("%3d: DNSServiceQueryRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
 
        mDNSPlatformMemZero(&request->u.queryrecord.q, sizeof(&request->u.queryrecord.q));
 
@@ -2736,7 +2742,8 @@ mDNSlocal mStatus handle_enum_request(request_state *request)
        mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
        if (interfaceIndex && !InterfaceID) return(mStatus_BadParamErr);
 
-       if (!request->msgptr) { LogMsg("%3d: DNSServiceEnumerateDomains(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
+       if (!request->msgptr)
+               { LogMsg("%3d: DNSServiceEnumerateDomains(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
 
        // allocate context structures
        uDNS_RegisterSearchDomains(&mDNSStorage);
@@ -2909,7 +2916,8 @@ mDNSlocal mStatus handle_port_mapping_request(request_state *request)
                ttl = get_uint32(&request->msgptr, request->msgend);
                }
 
-       if (!request->msgptr) { LogMsg("%3d: DNSServiceNATPortMappingCreate(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
+       if (!request->msgptr)
+               { LogMsg("%3d: DNSServiceNATPortMappingCreate(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
 
        if (protocol == 0)      // If protocol == 0 (i.e. just request public address) then IntPort, ExtPort, ttl must be zero too
                {
@@ -3554,9 +3562,10 @@ mDNSexport int udsserver_init(dnssd_sock_t skt)
        mDNS_GetDomains(&mDNSStorage, &mDNSStorage.AutomaticBrowseDomainQ, mDNS_DomainTypeBrowseAutomatic,
                mDNSNULL, mDNSInterface_LocalOnly, AutomaticBrowseDomainChange, mDNSNULL);
 
-       RegisterLocalOnlyDomainEnumPTR(&mDNSStorage, &localdomain, mDNS_DomainTypeRegistration);                // Add "local" as recommended registration domain ("dns-sd -E")
-       RegisterLocalOnlyDomainEnumPTR(&mDNSStorage, &localdomain, mDNS_DomainTypeBrowse);                              // Add "local" as recommended browsing domain ("dns-sd -F")
-       AddAutoBrowseDomain(0, &localdomain);                                                                                                                   // Add "local" as automatic browsing domain
+       // Add "local" as recommended registration domain ("dns-sd -E"), recommended browsing domain ("dns-sd -F"), and automatic browsing domain
+       RegisterLocalOnlyDomainEnumPTR(&mDNSStorage, &localdomain, mDNS_DomainTypeRegistration);
+       RegisterLocalOnlyDomainEnumPTR(&mDNSStorage, &localdomain, mDNS_DomainTypeBrowse);
+       AddAutoBrowseDomain(0, &localdomain);
 
        udsserver_handle_configchange(&mDNSStorage);
        return 0;
@@ -3787,7 +3796,8 @@ mDNSexport void udsserver_info(mDNS *const m)
                {
                ClientTunnel *c;
                for (c = m->TunnelClients; c; c = c->next)
-                       LogMsgNoIdent("%##s local %.16a %.4a remote %.16a %.4a %5d interval %d", c->dstname.c, &c->loc_inner, &c->loc_outer, &c->rmt_inner, &c->rmt_outer, mDNSVal16(c->rmt_outer_port), c->q.ThisQInterval);
+                       LogMsgNoIdent("%##s local %.16a %.4a remote %.16a %.4a %5d interval %d",
+                               c->dstname.c, &c->loc_inner, &c->loc_outer, &c->rmt_inner, &c->rmt_outer, mDNSVal16(c->rmt_outer_port), c->q.ThisQInterval);
                }
        #endif
        }