summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSCore
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-19 08:52:21 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-20 11:23:32 +0200
commitf761b290f135957f47e1c9af71b4a81c76c32b48 (patch)
tree2b7d273db4ff2388867efec5ad432fa49cd4047e /mDNSResponder/mDNSCore
parentmDNSResponder: Update to v576.30.4 (diff)
downloadrtems-libbsd-f761b290f135957f47e1c9af71b4a81c76c32b48.tar.bz2
mDNSResponder: Update to v625.41.2
The sources can be obtained via: https://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-625.41.2.tar.gz Update #3522.
Diffstat (limited to 'mDNSResponder/mDNSCore')
-rw-r--r--mDNSResponder/mDNSCore/CryptoAlg.c2
-rw-r--r--mDNSResponder/mDNSCore/CryptoAlg.h3
-rw-r--r--mDNSResponder/mDNSCore/DNSCommon.c119
-rw-r--r--mDNSResponder/mDNSCore/DNSCommon.h14
-rw-r--r--mDNSResponder/mDNSCore/DNSDigest.c3
-rw-r--r--mDNSResponder/mDNSCore/anonymous.c39
-rw-r--r--mDNSResponder/mDNSCore/anonymous.h2
-rw-r--r--mDNSResponder/mDNSCore/dnsproxy.c35
-rw-r--r--mDNSResponder/mDNSCore/dnsproxy.h3
-rw-r--r--mDNSResponder/mDNSCore/dnssec.c21
-rw-r--r--mDNSResponder/mDNSCore/dnssec.h3
-rwxr-xr-xmDNSResponder/mDNSCore/mDNS.c935
-rwxr-xr-xmDNSResponder/mDNSCore/mDNSDebug.h10
-rwxr-xr-xmDNSResponder/mDNSCore/mDNSEmbeddedAPI.h95
-rw-r--r--mDNSResponder/mDNSCore/nsec.c14
-rw-r--r--mDNSResponder/mDNSCore/nsec.h3
-rw-r--r--mDNSResponder/mDNSCore/nsec3.c28
-rw-r--r--mDNSResponder/mDNSCore/nsec3.h2
-rwxr-xr-xmDNSResponder/mDNSCore/uDNS.c66
19 files changed, 756 insertions, 641 deletions
diff --git a/mDNSResponder/mDNSCore/CryptoAlg.c b/mDNSResponder/mDNSCore/CryptoAlg.c
index 38533fc8..0008405d 100644
--- a/mDNSResponder/mDNSCore/CryptoAlg.c
+++ b/mDNSResponder/mDNSCore/CryptoAlg.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/mDNSResponder/mDNSCore/CryptoAlg.h b/mDNSResponder/mDNSCore/CryptoAlg.h
index 6cb3dc9d..c21507e4 100644
--- a/mDNSResponder/mDNSCore/CryptoAlg.h
+++ b/mDNSResponder/mDNSCore/CryptoAlg.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#ifndef __CRYPTO_ALG_H
#define __CRYPTO_ALG_H
diff --git a/mDNSResponder/mDNSCore/DNSCommon.c b/mDNSResponder/mDNSCore/DNSCommon.c
index 249e3b23..d364ee02 100644
--- a/mDNSResponder/mDNSCore/DNSCommon.c
+++ b/mDNSResponder/mDNSCore/DNSCommon.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -513,7 +513,7 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
expTimeBuf, inceptTimeBuf, swap16(rrsig->keyTag), ((domainname *)(&rrsig->signerName))->c);
len = DomainNameLength((domainname *)&rrsig->signerName);
- length += baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + len + RRSIG_FIXED_SIZE),
+ baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + len + RRSIG_FIXED_SIZE),
rr->rdlength - (len + RRSIG_FIXED_SIZE), ENC_BASE64);
}
break;
@@ -521,7 +521,7 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
rdataDNSKey *rrkey = (rdataDNSKey *)rd->data;
length += mDNS_snprintf(buffer+length, RemSpc, "\t%d %d %s %u ", swap16(rrkey->flags), rrkey->proto,
DNSSECAlgName(rrkey->alg), (unsigned int)keytag((mDNSu8 *)rrkey, rr->rdlength));
- length += baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + DNSKEY_FIXED_SIZE),
+ baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + DNSKEY_FIXED_SIZE),
rr->rdlength - DNSKEY_FIXED_SIZE, ENC_BASE64);
}
break;
@@ -1481,6 +1481,7 @@ mDNSexport void mDNS_SetupQuestion(DNSQuestion *const q, const mDNSInterfaceID I
q->qnameOrig = mDNSNULL;
q->AnonInfo = mDNSNULL;
q->pid = mDNSPlatformGetPID();
+ q->euid = 0;
q->DisallowPID = mDNSfalse;
q->ServiceID = -1;
q->QuestionCallback = callback;
@@ -2357,13 +2358,9 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
case kDNSType_NSEC: {
// For NSEC records, rdlength represents the exact number of bytes
// of in memory storage.
- int len = rr->rdlength;
mDNSu8 *nsec = (mDNSu8 *)rdb->data;
domainname *name = (domainname *)nsec;
- int dlen;
-
- dlen = DomainNameLength(name);
- len -= dlen;
+ const int dlen = DomainNameLength(name);
nsec += dlen;
// This function is called when we are sending a NSEC record as part of mDNS,
// or to copy the data to any other buffer needed which could be a mDNS or uDNS
@@ -2376,7 +2373,6 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
int i, j, wlen;
wlen = *(nsec + 1);
nsec += 2; // Skip the window number and len
- len -= 2;
// For our simplified use of NSEC synthetic records:
//
@@ -2406,6 +2402,7 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
else
{
int win, wlen;
+ int len = rr->rdlength - dlen;
// Sanity check whether the bitmap is good
while (len)
@@ -2607,7 +2604,7 @@ mDNSexport mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domain
}
// for dynamic updates
-mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease)
+mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease)
{
AuthRecord rr;
mDNS_SetupResourceRecord(&rr, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
@@ -2616,13 +2613,13 @@ mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease)
rr.resrec.rdestimate = sizeof(rdataOPT);
rr.resrec.rdata->u.opt[0].opt = kDNSOpt_Lease;
rr.resrec.rdata->u.opt[0].u.updatelease = lease;
- end = PutResourceRecordTTLJumbo(msg, end, &msg->h.numAdditionals, &rr.resrec, 0);
- if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTL"); return mDNSNULL; }
- return end;
+ ptr = PutResourceRecordTTLJumbo(msg, ptr, &msg->h.numAdditionals, &rr.resrec, 0);
+ if (!ptr) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTL"); return mDNSNULL; }
+ return ptr;
}
// for dynamic updates
-mDNSexport mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease, mDNSu8 *limit)
+mDNSexport mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease, mDNSu8 *limit)
{
AuthRecord rr;
mDNS_SetupResourceRecord(&rr, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
@@ -2631,9 +2628,9 @@ mDNSexport mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *end, mDNSu32
rr.resrec.rdestimate = sizeof(rdataOPT);
rr.resrec.rdata->u.opt[0].opt = kDNSOpt_Lease;
rr.resrec.rdata->u.opt[0].u.updatelease = lease;
- end = PutResourceRecordTTLWithLimit(msg, end, &msg->h.numAdditionals, &rr.resrec, 0, limit);
- if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
- return end;
+ ptr = PutResourceRecordTTLWithLimit(msg, ptr, &msg->h.numAdditionals, &rr.resrec, 0, limit);
+ if (!ptr) { LogMsg("ERROR: putUpdateLeaseWithLimit - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
+ return ptr;
}
mDNSexport mDNSu8 *putDNSSECOption(DNSMessage *msg, mDNSu8 *end, mDNSu8 *limit)
@@ -2650,7 +2647,7 @@ mDNSexport mDNSu8 *putDNSSECOption(DNSMessage *msg, mDNSu8 *end, mDNSu8 *limit)
// set the DO bit
ttl |= 0x8000;
end = PutResourceRecordTTLWithLimit(msg, end, &msg->h.numAdditionals, &rr.resrec, ttl, limit);
- if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
+ if (!end) { LogMsg("ERROR: putDNSSECOption - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
return end;
}
@@ -3441,12 +3438,7 @@ mDNSexport const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage
mDNSu16 pktrdlength;
if (largecr == &m->rec && m->rec.r.resrec.RecordType)
- {
- LogMsg("GetLargeResourceRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
-#if ForceAlerts
- *(long*)0 = 0;
-#endif
- }
+ LogFatalError("GetLargeResourceRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
rr->next = mDNSNULL;
rr->resrec.name = &largecr->namestorage;
@@ -3713,7 +3705,7 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
}
ptr = DumpRecords(m, msg, ptr, end, msg->h.numAnswers, IsUpdate ? "Prerequisites" : "Answers");
ptr = DumpRecords(m, msg, ptr, end, msg->h.numAuthorities, IsUpdate ? "Updates" : "Authorities");
- ptr = DumpRecords(m, msg, ptr, end, msg->h.numAdditionals, "Additionals");
+ DumpRecords(m, msg, ptr, end, msg->h.numAdditionals, "Additionals");
LogMsg("--------------");
}
@@ -3725,11 +3717,8 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
// Stub definition of TCPSocket_struct so we can access flags field. (Rest of TCPSocket_struct is platform-dependent.)
struct TCPSocket_struct { TCPSocketFlags flags; /* ... */ };
-
-struct UDPSocket_struct
-{
- mDNSIPPort port; // MUST BE FIRST FIELD -- mDNSCoreReceive expects every UDPSocket_struct to begin with mDNSIPPort port
-};
+// Stub definition of UDPSocket_struct so we can access port field. (Rest of UDPSocket_struct is platform-dependent.)
+struct UDPSocket_struct { mDNSIPPort port; /* ... */ };
// Note: When we sign a DNS message using DNSDigest_SignMessage(), the current real-time clock value is used, which
// is why we generally defer signing until we send the message, to ensure the signature is as fresh as possible.
@@ -3844,12 +3833,7 @@ mDNSexport void mDNS_Lock_(mDNS *const m, const char * const functionname)
// If that client callback does mDNS API calls, mDNS_reentrancy and mDNS_busy will both be one
// If mDNS_busy != mDNS_reentrancy that's a bad sign
if (m->mDNS_busy != m->mDNS_reentrancy)
- {
- LogMsg("%s: mDNS_Lock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
-#if ForceAlerts
- *(long*)0 = 0;
-#endif
- }
+ LogFatalError("%s: mDNS_Lock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
// If this is an initial entry into the mDNSCore code, set m->timenow
// else, if this is a re-entrant entry into the mDNSCore code, m->timenow should already be set
@@ -3930,82 +3914,89 @@ mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m)
return(e);
}
+#define LogTSE TSE++,LogMsg
+
mDNSexport void ShowTaskSchedulingError(mDNS *const m)
{
+ int TSE = 0;
AuthRecord *rr;
mDNS_Lock(m);
- LogMsg("Task Scheduling Error: Continuously busy for more than a second");
+ LogMsg("Task Scheduling Error: *** Continuously busy for more than a second");
// Note: To accurately diagnose *why* we're busy, the debugging code here needs to mirror the logic in GetNextScheduledEvent above
if (m->NewQuestions && (!m->NewQuestions->DelayAnswering || m->timenow - m->NewQuestions->DelayAnswering >= 0))
- LogMsg("Task Scheduling Error: NewQuestion %##s (%s)",
+ LogTSE("Task Scheduling Error: NewQuestion %##s (%s)",
m->NewQuestions->qname.c, DNSTypeName(m->NewQuestions->qtype));
if (m->NewLocalOnlyQuestions)
- LogMsg("Task Scheduling Error: NewLocalOnlyQuestions %##s (%s)",
+ LogTSE("Task Scheduling Error: NewLocalOnlyQuestions %##s (%s)",
m->NewLocalOnlyQuestions->qname.c, DNSTypeName(m->NewLocalOnlyQuestions->qtype));
if (m->NewLocalRecords)
{
rr = AnyLocalRecordReady(m);
- if (rr) LogMsg("Task Scheduling Error: NewLocalRecords %s", ARDisplayString(m, rr));
+ if (rr) LogTSE("Task Scheduling Error: NewLocalRecords %s", ARDisplayString(m, rr));
}
- if (m->NewLocalOnlyRecords) LogMsg("Task Scheduling Error: NewLocalOnlyRecords");
+ if (m->NewLocalOnlyRecords) LogTSE("Task Scheduling Error: NewLocalOnlyRecords");
- if (m->SPSProxyListChanged) LogMsg("Task Scheduling Error: SPSProxyListChanged");
- if (m->LocalRemoveEvents) LogMsg("Task Scheduling Error: LocalRemoveEvents");
+ if (m->SPSProxyListChanged) LogTSE("Task Scheduling Error: SPSProxyListChanged");
- if (m->timenow - m->NextScheduledEvent >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledEvent %d", m->timenow - m->NextScheduledEvent);
+ if (m->LocalRemoveEvents) LogTSE("Task Scheduling Error: LocalRemoveEvents");
#ifndef UNICAST_DISABLED
if (m->timenow - m->NextuDNSEvent >= 0)
- LogMsg("Task Scheduling Error: m->NextuDNSEvent %d", m->timenow - m->NextuDNSEvent);
+ LogTSE("Task Scheduling Error: m->NextuDNSEvent %d", m->timenow - m->NextuDNSEvent);
if (m->timenow - m->NextScheduledNATOp >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledNATOp %d", m->timenow - m->NextScheduledNATOp);
+ LogTSE("Task Scheduling Error: m->NextScheduledNATOp %d", m->timenow - m->NextScheduledNATOp);
if (m->NextSRVUpdate && m->timenow - m->NextSRVUpdate >= 0)
- LogMsg("Task Scheduling Error: m->NextSRVUpdate %d", m->timenow - m->NextSRVUpdate);
+ LogTSE("Task Scheduling Error: m->NextSRVUpdate %d", m->timenow - m->NextSRVUpdate);
#endif
if (m->timenow - m->NextCacheCheck >= 0)
- LogMsg("Task Scheduling Error: m->NextCacheCheck %d", m->timenow - m->NextCacheCheck);
+ LogTSE("Task Scheduling Error: m->NextCacheCheck %d", m->timenow - m->NextCacheCheck);
if (m->timenow - m->NextScheduledSPS >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledSPS %d", m->timenow - m->NextScheduledSPS);
+ LogTSE("Task Scheduling Error: m->NextScheduledSPS %d", m->timenow - m->NextScheduledSPS);
if (m->timenow - m->NextScheduledKA >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledKA %d", m->timenow - m->NextScheduledKA);
+ LogTSE("Task Scheduling Error: m->NextScheduledKA %d", m->timenow - m->NextScheduledKA);
if (!m->DelaySleep && m->SleepLimit && m->timenow - m->NextScheduledSPRetry >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledSPRetry %d", m->timenow - m->NextScheduledSPRetry);
+ LogTSE("Task Scheduling Error: m->NextScheduledSPRetry %d", m->timenow - m->NextScheduledSPRetry);
if (m->DelaySleep && m->timenow - m->DelaySleep >= 0)
- LogMsg("Task Scheduling Error: m->DelaySleep %d", m->timenow - m->DelaySleep);
+ LogTSE("Task Scheduling Error: m->DelaySleep %d", m->timenow - m->DelaySleep);
if (m->SuppressSending && m->timenow - m->SuppressSending >= 0)
- LogMsg("Task Scheduling Error: m->SuppressSending %d", m->timenow - m->SuppressSending);
+ LogTSE("Task Scheduling Error: m->SuppressSending %d", m->timenow - m->SuppressSending);
if (m->timenow - m->NextScheduledQuery >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledQuery %d", m->timenow - m->NextScheduledQuery);
+ LogTSE("Task Scheduling Error: m->NextScheduledQuery %d", m->timenow - m->NextScheduledQuery);
if (m->timenow - m->NextScheduledProbe >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledProbe %d", m->timenow - m->NextScheduledProbe);
+ LogTSE("Task Scheduling Error: m->NextScheduledProbe %d", m->timenow - m->NextScheduledProbe);
if (m->timenow - m->NextScheduledResponse >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledResponse %d", m->timenow - m->NextScheduledResponse);
+ LogTSE("Task Scheduling Error: m->NextScheduledResponse %d", m->timenow - m->NextScheduledResponse);
+ if (m->timenow - m->NextScheduledStopTime >= 0)
+ LogTSE("Task Scheduling Error: m->NextScheduledStopTime %d", m->timenow - m->NextScheduledStopTime);
+
+ if (m->timenow - m->NextScheduledEvent >= 0)
+ LogTSE("Task Scheduling Error: m->NextScheduledEvent %d", m->timenow - m->NextScheduledEvent);
+
+ if (m->NetworkChanged && m->timenow - m->NetworkChanged >= 0)
+ LogTSE("Task Scheduling Error: NetworkChanged %d", m->timenow - m->NetworkChanged);
+
+ if (!TSE) LogMsg("Task Scheduling Error: *** No likely causes identified");
+ else LogMsg("Task Scheduling Error: *** %d potential cause%s identified (significant only if the same cause consistently appears)", TSE, TSE > 1 ? "s" : "");
mDNS_Unlock(m);
}
-mDNSexport void mDNS_Unlock_(mDNS *const m, const char * const functionname)
+mDNSexport void mDNS_Unlock_(mDNS *const m, const char *const functionname)
{
// Decrement mDNS_busy
m->mDNS_busy--;
// Check for locking failures
if (m->mDNS_busy != m->mDNS_reentrancy)
- {
- LogMsg("%s: mDNS_Unlock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
-#if ForceAlerts
- *(long*)0 = 0;
-#endif
- }
+ LogFatalError("%s: mDNS_Unlock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
// If this is a final exit from the mDNSCore code, set m->NextScheduledEvent and clear m->timenow
if (m->mDNS_busy == 0)
diff --git a/mDNSResponder/mDNSCore/DNSCommon.h b/mDNSResponder/mDNSCore/DNSCommon.h
index b92f5a9a..e51b06dd 100644
--- a/mDNSResponder/mDNSCore/DNSCommon.h
+++ b/mDNSResponder/mDNSCore/DNSCommon.h
@@ -220,7 +220,7 @@ extern mDNSu8 *putDeletionRecord(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *r
extern mDNSu8 *putDeletionRecordWithLimit(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *rr, mDNSu8 *limit);
extern mDNSu8 *putDeleteRRSetWithLimit(DNSMessage *msg, mDNSu8 *ptr, const domainname *name, mDNSu16 rrtype, mDNSu8 *limit);
extern mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domainname *name);
-extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease);
+extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease);
extern mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease, mDNSu8 *limit);
extern mDNSu8 *putHINFO(const mDNS *const m, DNSMessage *const msg, mDNSu8 *ptr, DomainAuthInfo *authInfo, mDNSu8 *limit);
@@ -297,16 +297,16 @@ extern void mDNS_Unlock_(mDNS *const m, const char * const functionname);
#define mDNS_Unlock(X) mDNS_Unlock_((X), __func__)
-#define mDNS_CheckLock(X) { if ((X)->mDNS_busy != (X)->mDNS_reentrancy+1) \
- LogMsg("%s: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", __func__, (X)->mDNS_busy, (X)->mDNS_reentrancy); }
+#define mDNS_CheckLock(X) \
+ if ((X)->mDNS_busy != (X)->mDNS_reentrancy+1) LogMsg("%s: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", __func__, (X)->mDNS_busy, (X)->mDNS_reentrancy)
#define mDNS_DropLockBeforeCallback() do { m->mDNS_reentrancy++; \
- if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Locking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
-} while (0)
+ if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Locking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
+ } while (0)
#define mDNS_ReclaimLockAfterCallback() do { \
- if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Unlocking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
- m->mDNS_reentrancy--; } while (0)
+ if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Unlocking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
+ m->mDNS_reentrancy--; } while (0)
#ifdef __cplusplus
}
diff --git a/mDNSResponder/mDNSCore/DNSDigest.c b/mDNSResponder/mDNSCore/DNSDigest.c
index 33798d38..57a40120 100644
--- a/mDNSResponder/mDNSCore/DNSDigest.c
+++ b/mDNSResponder/mDNSCore/DNSDigest.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2011 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
* limitations under the License.
*/
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/mDNSResponder/mDNSCore/anonymous.c b/mDNSResponder/mDNSCore/anonymous.c
index 55a83175..779e4ea6 100644
--- a/mDNSResponder/mDNSCore/anonymous.c
+++ b/mDNSResponder/mDNSCore/anonymous.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,14 @@
#define ANON_NSEC3_ITERATIONS 1
+struct AnonInfoResourceRecord_struct
+{
+ ResourceRecord resrec;
+ RData rdatastorage;
+};
+
+typedef struct AnonInfoResourceRecord_struct AnonInfoResourceRecord;
+
mDNSlocal mDNSBool InitializeNSEC3Record(ResourceRecord *rr, const mDNSu8 *AnonData, int len, mDNSu32 salt)
{
const mDNSu8 *ptr;
@@ -118,9 +126,10 @@ mDNSlocal ResourceRecord *ConstructNSEC3Record(const domainname *service, const
mDNSlocal ResourceRecord *CopyNSEC3ResourceRecord(AnonymousInfo *si, const ResourceRecord *rr)
{
- int len;
+ AnonInfoResourceRecord *anonRR;
domainname *name;
- ResourceRecord *nsec3rr;
+ mDNSu32 neededLen;
+ mDNSu32 extraLen;
if (rr->rdlength < MCAST_NSEC3_RDLENGTH)
{
@@ -128,22 +137,26 @@ mDNSlocal ResourceRecord *CopyNSEC3ResourceRecord(AnonymousInfo *si, const Resou
return mDNSNULL;
}
// Allocate space for the name and the rdata along with the ResourceRecord
- len = DomainNameLength(rr->name);
- nsec3rr = mDNSPlatformMemAllocate(sizeof(ResourceRecord) + len + sizeof(RData));
- if (!nsec3rr)
+ neededLen = rr->rdlength + DomainNameLength(rr->name);
+ extraLen = (neededLen > sizeof(RDataBody)) ? (neededLen - sizeof(RDataBody)) : 0;
+ anonRR = (AnonInfoResourceRecord *)mDNSPlatformMemAllocate(sizeof(AnonInfoResourceRecord) + extraLen);
+ if (!anonRR)
return mDNSNULL;
- *nsec3rr = *rr;
- name = (domainname *)((mDNSu8 *)nsec3rr + sizeof(ResourceRecord));
- nsec3rr->name = (const domainname *)name;
+ anonRR->resrec = *rr;
+
+ anonRR->rdatastorage.MaxRDLength = rr->rdlength;
+ mDNSPlatformMemCopy(anonRR->rdatastorage.u.data, rr->rdata->u.data, rr->rdlength);
+
+ name = (domainname *)(anonRR->rdatastorage.u.data + rr->rdlength);
AssignDomainName(name, rr->name);
- nsec3rr->rdata = (RData *)((mDNSu8 *)nsec3rr->name + len);
- mDNSPlatformMemCopy(nsec3rr->rdata->u.data, rr->rdata->u.data, rr->rdlength);
+ anonRR->resrec.name = name;
+ anonRR->resrec.rdata = &anonRR->rdatastorage;
- si->nsec3RR = nsec3rr;
+ si->nsec3RR = (ResourceRecord *)anonRR;
- return nsec3rr;
+ return si->nsec3RR;
}
// When a service is started or a browse is started with the Anonymous data, we allocate a new random
diff --git a/mDNSResponder/mDNSCore/anonymous.h b/mDNSResponder/mDNSCore/anonymous.h
index 2f2b4f8c..b60812ea 100644
--- a/mDNSResponder/mDNSCore/anonymous.h
+++ b/mDNSResponder/mDNSCore/anonymous.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/mDNSResponder/mDNSCore/dnsproxy.c b/mDNSResponder/mDNSCore/dnsproxy.c
index 11bacc10..5b358864 100644
--- a/mDNSResponder/mDNSCore/dnsproxy.c
+++ b/mDNSResponder/mDNSCore/dnsproxy.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -83,10 +83,6 @@ mDNSlocal void FreeDNSProxyClient(DNSProxyClient *pc)
mDNSlocal mDNSBool ParseEDNS0(DNSProxyClient *pc, const mDNSu8 *ptr, int length, const mDNSu8 *limit)
{
- mDNSu16 rrtype, rrclass;
- mDNSu8 rcode, version;
- mDNSu16 flag;
-
if (ptr + length > limit)
{
LogInfo("ParseEDNS0: Not enough space in the packet");
@@ -94,18 +90,19 @@ mDNSlocal mDNSBool ParseEDNS0(DNSProxyClient *pc, const mDNSu8 *ptr, int length,
}
// Skip the root label
ptr++;
- rrtype = (mDNSu16) ((mDNSu16)ptr[0] << 8 | ptr[1]);
+ mDNSu16 rrtype = (mDNSu16) ((mDNSu16)ptr[0] << 8 | ptr[1]);
if (rrtype != kDNSType_OPT)
{
LogInfo("ParseEDNS0: Not the right type %d", rrtype);
return mDNSfalse;
}
- rrclass = (mDNSu16) ((mDNSu16)ptr[2] << 8 | ptr[3]);
- rcode = ptr[4];
- version = ptr[5];
- flag = (mDNSu16) ((mDNSu16)ptr[6] << 8 | ptr[7]);
-
+ mDNSu16 rrclass = (mDNSu16) ((mDNSu16)ptr[2] << 8 | ptr[3]);
+#if MDNS_DEBUGMSGS
+ mDNSu8 rcode = ptr[4];
+ mDNSu8 version = ptr[5];
+ mDNSu16 flag = (mDNSu16) ((mDNSu16)ptr[6] << 8 | ptr[7]);
debugf("rrtype is %s, length is %d, rcode %d, version %d, flag 0x%x", DNSTypeName(rrtype), rrclass, rcode, version, flag);
+#endif
pc->rcvBufSize = rrclass;
pc->DNSSECOK = ptr[6] & 0x80;
@@ -366,7 +363,7 @@ again:
return mDNSNULL;
}
len += (ptr - orig);
- orig = ptr;
+ // orig = ptr; Commented out to avoid ‘value never read’ error message
}
LogInfo("AddResourceRecord: Added %d bytes to the packet", len);
return ptr;
@@ -471,14 +468,16 @@ mDNSlocal void ProxyClientCallback(mDNS *const m, DNSQuestion *question, const R
}
}
}
+
+ debugf("ProxyClientCallback: InterfaceID is %p for response to client", pc->interfaceID);
if (!pc->tcp)
{
- mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, (UDPSocket *)pc->socket, &pc->addr, pc->port, mDNSNULL, mDNSNULL, mDNSfalse);
+ mDNSSendDNSMessage(m, &m->omsg, ptr, pc->interfaceID, (UDPSocket *)pc->socket, &pc->addr, pc->port, mDNSNULL, mDNSNULL, mDNSfalse);
}
else
{
- mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, mDNSNULL, &pc->addr, pc->port, (TCPSocket *)pc->socket, mDNSNULL, mDNSfalse);
+ mDNSSendDNSMessage(m, &m->omsg, ptr, pc->interfaceID, mDNSNULL, &pc->addr, pc->port, (TCPSocket *)pc->socket, mDNSNULL, mDNSfalse);
}
done:
@@ -502,8 +501,6 @@ mDNSlocal void SendError(mDNS *const m, void *socket, void *const pkt, const mDN
int pktlen = (int)(end - (mDNSu8 *)pkt);
DNSMessage *msg = (DNSMessage *)pkt;
- (void) InterfaceID;
-
// RFC 1035 requires that we copy the question back and RFC 2136 is okay with sending nothing
// in the body or send back whatever we get for updates. It is easy to return whatever we get
// in the question back to the responder. We return as much as we can fit in our standard
@@ -517,12 +514,12 @@ mDNSlocal void SendError(mDNS *const m, void *socket, void *const pkt, const mDN
mDNSPlatformMemCopy(m->omsg.data, (mDNSu8 *)&msg->h.numQuestions, pktlen);
if (!tcp)
{
- mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, mDNSInterface_Any, socket, dstaddr, dstport, mDNSNULL, mDNSNULL,
+ mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, InterfaceID, socket, dstaddr, dstport, mDNSNULL, mDNSNULL,
mDNSfalse);
}
else
{
- mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, mDNSInterface_Any, mDNSNULL, dstaddr, dstport, (TCPSocket *)socket,
+ mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, InterfaceID, mDNSNULL, dstaddr, dstport, (TCPSocket *)socket,
mDNSNULL, mDNSfalse);
}
mDNSPlatformDisposeProxyContext(context);
@@ -576,7 +573,7 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, void *const pkt,
const mDNSu8 *ptr;
DNSQuestion q, *qptr;
DNSProxyClient *pc;
- const mDNSu8 *optRR;
+ const mDNSu8 *optRR = mDNSNULL;
int optLen = 0;
DNSProxyClient **ppc = &DNSProxyClients;
diff --git a/mDNSResponder/mDNSCore/dnsproxy.h b/mDNSResponder/mDNSCore/dnsproxy.h
index ed46a125..8aa3d007 100644
--- a/mDNSResponder/mDNSCore/dnsproxy.h
+++ b/mDNSResponder/mDNSCore/dnsproxy.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#ifndef __DNS_PROXY_H
#define __DNS_PROXY_H
diff --git a/mDNSResponder/mDNSCore/dnssec.c b/mDNSResponder/mDNSCore/dnssec.c
index c83b8413..bf9acfe8 100644
--- a/mDNSResponder/mDNSCore/dnssec.c
+++ b/mDNSResponder/mDNSCore/dnssec.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#include "mDNSEmbeddedAPI.h"
#include "DNSSECSupport.h"
#include "DNSCommon.h"
@@ -309,7 +310,7 @@ mDNSlocal AuthChain *AuthChainCopy(AuthChain *ae)
rvfrom = ae->rrset;
rvto = &ac->rrset;
- while (rvfrom)
+ while (rvfrom && rvto)
{
*rvto = CopyRRVerifier(rvfrom);
rvfrom = rvfrom->next;
@@ -318,7 +319,7 @@ mDNSlocal AuthChain *AuthChainCopy(AuthChain *ae)
rvfrom = ae->rrsig;
rvto = &ac->rrsig;
- while (rvfrom)
+ while (rvfrom && rvto)
{
*rvto = CopyRRVerifier(rvfrom);
rvfrom = rvfrom->next;
@@ -327,7 +328,7 @@ mDNSlocal AuthChain *AuthChainCopy(AuthChain *ae)
rvfrom = ae->key;
rvto = &ac->key;
- while (rvfrom)
+ while (rvfrom && rvto)
{
*rvto = CopyRRVerifier(rvfrom);
rvfrom = rvfrom->next;
@@ -1065,7 +1066,6 @@ mDNSlocal mStatus CheckDSForKey(mDNS *const m, DNSSECVerifier *dv, CacheRecord *
return mStatus_NoError;
else
return mStatus_NoSuchRecord;
- return (dv->ds ? mStatus_NoError : mStatus_NoSuchRecord);
}
// It returns mDNStrue if we have all the rrsets for verification and mDNSfalse otherwise.
@@ -2335,8 +2335,6 @@ mDNSlocal void SetTTLRRSet(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus statu
rdataRRSig *rrsig;
mDNSu32 slot;
CacheGroup *cg;
- int sigNameLen, len;
- mDNSu8 *ptr;
mDNSu32 rrTTL, rrsigTTL, rrsigOrigTTL, rrsigTimeTTL;
domainname *qname;
mDNSu16 qtype;
@@ -2400,17 +2398,11 @@ mDNSlocal void SetTTLRRSet(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus statu
{
rrsigv = dv->ac->rrsig;
rrsig = (rdataRRSig *)rrsigv->rdata;
- sigNameLen = DomainNameLength((domainname *)&rrsig->signerName);
- // pointer to signature and the length
- ptr = (mDNSu8 *)(rrsigv->rdata + sigNameLen + RRSIG_FIXED_SIZE);
- len = rrsigv->rdlength - RRSIG_FIXED_SIZE - sigNameLen;
}
else
{
rrsigv = mDNSNULL;
rrsig = mDNSNULL;
- ptr = mDNSNULL;
- sigNameLen = len = 0;
}
rrsigRR = mDNSNULL;
@@ -3187,14 +3179,11 @@ mDNSexport void VerifySignature(mDNS *const m, DNSSECVerifier *dv, DNSQuestion *
mDNSlocal mDNSBool TrustedKeyPresent(mDNS *const m, DNSSECVerifier *dv)
{
- rdataRRSig *rrsig;
rdataDS *ds;
rdataDNSKey *key;
TrustAnchor *ta;
RRVerifier *keyv;
- rrsig = (rdataRRSig *)dv->rrsig->rdata;
-
// Walk all our trusted DS Records to see if we have a matching DNS KEY record that verifies
// the hash. If we find one, verify that this key was used to sign the KEY rrsets in
// this zone. Loop till we find one.
diff --git a/mDNSResponder/mDNSCore/dnssec.h b/mDNSResponder/mDNSCore/dnssec.h
index 1a8d9535..b770af8d 100644
--- a/mDNSResponder/mDNSCore/dnssec.h
+++ b/mDNSResponder/mDNSCore/dnssec.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#ifndef __DNSSEC_H
#define __DNSSEC_H
diff --git a/mDNSResponder/mDNSCore/mDNS.c b/mDNSResponder/mDNSCore/mDNS.c
index e0af1f1a..6b02be46 100755
--- a/mDNSResponder/mDNSCore/mDNS.c
+++ b/mDNSResponder/mDNSCore/mDNS.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,7 +47,6 @@
#include "dns_sd.h" // for kDNSServiceFlags* definitions
#if APPLE_OSX_mDNSResponder
-
#include <WebFilterDNS/WebFilterDNS.h>
#if !NO_WCF
@@ -63,6 +62,10 @@ void WCFConnectionDealloc(WCFConnection* c) __attribute__((weak_import));
#define NO_WCF 1
#endif // APPLE_OSX_mDNSResponder
+#if TARGET_OS_EMBEDDED
+#include "Metrics.h"
+#endif
+
// Forward declarations
mDNSlocal void BeginSleepProcessing(mDNS *const m);
mDNSlocal void RetrySPSRegistrations(mDNS *const m);
@@ -80,6 +83,7 @@ mDNSlocal void DeadvertiseAllInterfaceRecords(mDNS *const m);
mDNSlocal void FreeNSECRecords(mDNS *const m, CacheRecord *NSECRecords);
mDNSlocal void mDNSParseNSEC3Records(mDNS *const m, const DNSMessage *const response, const mDNSu8 *end,
const mDNSInterfaceID InterfaceID, CacheRecord **NSEC3Records);
+mDNSlocal mDNSu8 *GetValueForMACAddr(mDNSu8 *ptr, mDNSu8 *limit, mDNSEthAddr *eth);
// ***************************************************************************
@@ -146,10 +150,6 @@ mDNSlocal void SetNextQueryStopTime(mDNS *const m, const DNSQuestion *const q)
{
mDNS_CheckLock(m);
-#if ForceAlerts
- if (m->mDNS_busy != m->mDNS_reentrancy+1) *(long*)0 = 0;
-#endif
-
if (m->NextScheduledStopTime - q->StopTime > 0)
m->NextScheduledStopTime = q->StopTime;
}
@@ -158,10 +158,6 @@ mDNSexport void SetNextQueryTime(mDNS *const m, const DNSQuestion *const q)
{
mDNS_CheckLock(m);
-#if ForceAlerts
- if (m->mDNS_busy != m->mDNS_reentrancy+1) *(long*)0 = 0;
-#endif
-
if (ActiveQuestion(q))
{
// Depending on whether this is a multicast or unicast question we want to set either:
@@ -352,7 +348,7 @@ mDNSlocal CacheGroup *CacheGroupForRecord(const mDNS *const m, const mDNSu32 slo
return(CacheGroupForName(m, slot, rr->namehash, rr->name));
}
-mDNSexport mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr, mDNSBool *myself)
+mDNSexport mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr)
{
NetworkInterfaceInfo *intf;
@@ -363,44 +359,19 @@ mDNSexport mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterface
for (intf = m->HostInterfaces; intf; intf = intf->next)
if (intf->ip.type == addr->type && intf->InterfaceID == InterfaceID && intf->McastTxRx)
if (((intf->ip.ip.v4.NotAnInteger ^ addr->ip.v4.NotAnInteger) & intf->mask.ip.v4.NotAnInteger) == 0)
- {
- if (myself)
- {
- if (mDNSSameIPv4Address(intf->ip.ip.v4, addr->ip.v4))
- *myself = mDNStrue;
- else
- *myself = mDNSfalse;
- if (*myself)
- debugf("mDNS_AddressIsLocalSubnet: IPv4 %#a returning true", addr);
- else
- debugf("mDNS_AddressIsLocalSubnet: IPv4 %#a returning false", addr);
- }
return(mDNStrue);
- }
}
if (addr->type == mDNSAddrType_IPv6)
{
+ if (mDNSv6AddressIsLinkLocal(&addr->ip.v6)) return(mDNStrue);
for (intf = m->HostInterfaces; intf; intf = intf->next)
if (intf->ip.type == addr->type && intf->InterfaceID == InterfaceID && intf->McastTxRx)
if ((((intf->ip.ip.v6.l[0] ^ addr->ip.v6.l[0]) & intf->mask.ip.v6.l[0]) == 0) &&
(((intf->ip.ip.v6.l[1] ^ addr->ip.v6.l[1]) & intf->mask.ip.v6.l[1]) == 0) &&
(((intf->ip.ip.v6.l[2] ^ addr->ip.v6.l[2]) & intf->mask.ip.v6.l[2]) == 0) &&
(((intf->ip.ip.v6.l[3] ^ addr->ip.v6.l[3]) & intf->mask.ip.v6.l[3]) == 0))
- {
- if (myself)
- {
- if (mDNSSameIPv6Address(intf->ip.ip.v6, addr->ip.v6))
- *myself = mDNStrue;
- else
- *myself = mDNSfalse;
- if (*myself)
- debugf("mDNS_AddressIsLocalSubnet: IPv6 %#a returning true", addr);
- else
- debugf("mDNS_AddressIsLocalSubnet: IPv6 %#a returning false", addr);
- }
return(mDNStrue);
- }
}
return(mDNSfalse);
@@ -475,11 +446,20 @@ mDNSexport void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, Re
const mDNSu32 c = q->CNAMEReferrals + 1; // Stash a copy of the new q->CNAMEReferrals value
UDPSocket *sock = q->LocalSocket;
mDNSOpaque16 id = q->TargetQID;
+#if TARGET_OS_EMBEDDED
+ domainname *originalQName;
+#endif
// if there is a message waiting at the socket, we want to process that instead
// of throwing it away. If we have a CNAME response that answers
// both A and AAAA question and while answering it we don't want to throw
// away the response where the actual addresses are present.
+ // This is a stupid hack and we should get rid of it.
+ // The chance of there being a second unicast UDP packet already waiting in the kernel before we’ve
+ // finished processing the previous one is virtually nil, and will only happen by luck on very rare
+ // occasions when running on a machine with a fast network connection and a slow or busy processor.
+ // The idea that we’d rely for correctness on this random chance event occurring is ridiculous.
+ // -- SC
if (mDNSPlatformPeekUDP(m, q->LocalSocket))
{
LogInfo("AnswerQuestionByFollowingCNAME: Preserving UDP socket for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
@@ -508,6 +488,31 @@ mDNSexport void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, Re
LogInfo("AnswerQuestionByFollowingCNAME: %p %##s (%s) following CNAME referral %d for %s",
q, q->qname.c, DNSTypeName(q->qtype), q->CNAMEReferrals, RRDisplayString(m, rr));
+#if TARGET_OS_EMBEDDED
+ if (q->metrics.originalQName)
+ {
+ originalQName = q->metrics.originalQName;
+ q->metrics.originalQName = mDNSNULL;
+ }
+ else
+ {
+ mDNSu16 qNameLen;
+
+ qNameLen = DomainNameLength(&q->qname);
+ if ((qNameLen > 0) && (qNameLen <= MAX_DOMAIN_NAME))
+ {
+ originalQName = mDNSPlatformMemAllocate(qNameLen);
+ if (originalQName)
+ {
+ mDNSPlatformMemCopy(originalQName->c, q->qname.c, qNameLen);
+ }
+ }
+ else
+ {
+ originalQName = mDNSNULL;
+ }
+ }
+#endif
mDNS_StopQuery_internal(m, q); // Stop old query
AssignDomainName(&q->qname, &rr->rdata->u.name); // Update qname
q->qnamehash = DomainNameHashValue(&q->qname); // and namehash
@@ -524,6 +529,9 @@ mDNSexport void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, Re
// Record how many times we've done this. We need to do this *after* mDNS_StartQuery_internal,
// because mDNS_StartQuery_internal re-initializes CNAMEReferrals to zero
q->CNAMEReferrals = c;
+#if TARGET_OS_EMBEDDED
+ q->metrics.originalQName = originalQName;
+#endif
if (sock)
{
// We have a message waiting and that should answer this question.
@@ -933,7 +941,7 @@ mDNSlocal void SetTargetToHostName(mDNS *const m, AuthRecord *const rr)
{
const domainname *const n = SetUnicastTargetToHostName(m, rr);
if (n) newname = n;
- else { target->c[0] = 0; SetNewRData(&rr->resrec, mDNSNULL, 0); return; }
+ else { if (target) target->c[0] = 0; SetNewRData(&rr->resrec, mDNSNULL, 0); return; }
}
if (target && SameDomainName(target, newname))
@@ -1133,26 +1141,61 @@ mDNSlocal AuthRecord *CheckAuthSameRecord(AuthHash *r, AuthRecord *rr)
mDNSlocal void DecrementAutoTargetServices(mDNS *const m, AuthRecord *const rr)
{
+ if (RRLocalOnly(rr))
+ {
+ // A sanity check, this should be prevented in calling code.
+ LogInfo("DecrementAutoTargetServices: called for RRLocalOnly() record: %s", ARDisplayString(m, rr));
+ return;
+ }
+
if (!AuthRecord_uDNS(rr) && rr->resrec.rrtype == kDNSType_SRV && rr->AutoTarget == Target_AutoHost)
{
- m->AutoTargetServices--;
- LogInfo("DecrementAutoTargetServices: AutoService Record %s, AutoTargetServices %d", ARDisplayString(m, rr), m->AutoTargetServices);
- if (!m->AutoTargetServices)
+ // If about to get rid of the last advertised service
+ if (m->AutoTargetServices == 1)
DeadvertiseAllInterfaceRecords(m);
+
+ m->AutoTargetServices--;
+ LogInfo("DecrementAutoTargetServices: AutoTargetServices %d Record %s", m->AutoTargetServices, ARDisplayString(m, rr));
+ }
+
+#if TARGET_OS_WATCH
+ if (!AuthRecord_uDNS(rr))
+ {
+ if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
+ m->NetworkChanged = m->timenow;
+ m->NumAllInterfaceRecords--;
+ LogInfo("DecrementAutoTargetServices: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %s",
+ m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, ARDisplayString(m, rr));
}
+#endif
}
mDNSlocal void IncrementAutoTargetServices(mDNS *const m, AuthRecord *const rr)
{
- if (!AuthRecord_uDNS(rr) && rr->resrec.rrtype == kDNSType_SRV && rr->AutoTarget == Target_AutoHost)
+ if (RRLocalOnly(rr))
+ {
+ // A sanity check, this should be prevented in calling code.
+ LogInfo("IncrementAutoTargetServices: called for RRLocalOnly() record: %s", ARDisplayString(m, rr));
+ return;
+ }
+
+#if TARGET_OS_WATCH
+ if (!AuthRecord_uDNS(rr))
{
- int count = m->AutoTargetServices;
+ m->NumAllInterfaceRecords++;
+ LogInfo("IncrementAutoTargetServices: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %s",
+ m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, ARDisplayString(m, rr));
+ if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
+ m->NetworkChanged = m->timenow;
+ }
+#endif
- // Bump up before calling AdvertiseAllInterfaceRecords. AdvertiseInterface
- // returns without doing anything if the count is zero.
+ if (!AuthRecord_uDNS(rr) && rr->resrec.rrtype == kDNSType_SRV && rr->AutoTarget == Target_AutoHost)
+ {
m->AutoTargetServices++;
- LogInfo("IncrementAutoTargetServices: AutoService Record %s, AutoTargetServices %d", ARDisplayString(m, rr), m->AutoTargetServices);
- if (!count)
+ LogInfo("IncrementAutoTargetServices: AutoTargetServices %d Record %s", m->AutoTargetServices, ARDisplayString(m, rr));
+ // If this is the first advertised service
+ if (m->AutoTargetServices == 1)
AdvertiseAllInterfaceRecords(m);
}
}
@@ -1378,6 +1421,7 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
// (kDNSRecordTypeDeregistering) so that we deliver RMV events to the application. But this causes more
// complications and not clear whether there are any benefits. See rdar:9304275 for details.
// Hence, just bail out.
+ // This comment is doesn’t make any sense. -- SC
if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
{
if (CheckAuthRecordConflict(&m->rrauth, rr))
@@ -1443,11 +1487,12 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
{
AuthGroup *ag;
ag = InsertAuthRecord(m, &m->rrauth, rr);
- if (ag && !ag->NewLocalOnlyRecords) {
+ if (ag && !ag->NewLocalOnlyRecords)
+ {
m->NewLocalOnlyRecords = mDNStrue;
ag->NewLocalOnlyRecords = rr;
}
- // No probing for LocalOnly records, Acknowledge them right away
+ // No probing for LocalOnly records; acknowledge them right away
if (rr->resrec.RecordType == kDNSRecordTypeUnique) rr->resrec.RecordType = kDNSRecordTypeVerified;
AcknowledgeRecord(m, rr);
return(mStatus_NoError);
@@ -1459,15 +1504,15 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
}
}
- // If this is a keepalive record, fetch the MAC address of the remote host.
+ // If this is a non-sleep proxy keepalive record, fetch the MAC address of the remote host.
// This is used by the in-NIC proxy to send the keepalive packets.
- if (mDNS_KeepaliveRecord(&rr->resrec))
+ if (!rr->WakeUp.HMAC.l[0] && mDNS_KeepaliveRecord(&rr->resrec))
{
+ mDNSAddr raddr;
// Set the record type to known unique to prevent probing keep alive records.
// Also make sure we do not announce the keepalive records.
rr->resrec.RecordType = kDNSRecordTypeKnownUnique;
rr->AnnounceCount = 0;
- mDNSAddr raddr;
getKeepaliveRaddr(m, rr, &raddr);
// This is an asynchronous call. Once the remote MAC address is available, helper will schedule an
// asynchronous task to update the resource record
@@ -1476,8 +1521,9 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
if (!AuthRecord_uDNS(rr)) // This check is superfluous, given that for unicast records we (currently) bail out above
{
- // We have inserted the record in the list. See if we have to advertise the A/AAAA,HINFO,PTR records.
+ // We have inserted the record in the list. See if we have to advertise the A/AAAA, HINFO, PTR records.
IncrementAutoTargetServices(m, rr);
+
// For records that are not going to probe, acknowledge them right away
if (rr->resrec.RecordType != kDNSRecordTypeUnique && rr->resrec.RecordType != kDNSRecordTypeDeregistering)
AcknowledgeRecord(m, rr);
@@ -2361,8 +2407,8 @@ mDNSlocal void SendResponses(mDNS *const m)
LogSPS("SendResponses: Sending wakeup %2d for %.6a %s", rr->AnnounceCount-3, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
SendWakeup(m, rr->resrec.InterfaceID, &rr->WakeUp.IMAC, &rr->WakeUp.password);
for (r2 = rr; r2; r2=r2->next)
- if (r2->AnnounceCount && r2->resrec.InterfaceID == rr->resrec.InterfaceID && mDNSSameEthAddress(&r2->WakeUp.IMAC, &rr->WakeUp.IMAC) &&
- !mDNSSameEthAddress(&zeroEthAddr, &r2->WakeUp.HMAC))
+ if ((r2->resrec.RecordType == kDNSRecordTypeDeregistering) && r2->AnnounceCount && (r2->resrec.InterfaceID == rr->resrec.InterfaceID) &&
+ mDNSSameEthAddress(&r2->WakeUp.IMAC, &rr->WakeUp.IMAC) && !mDNSSameEthAddress(&zeroEthAddr, &r2->WakeUp.HMAC))
{
// For now we only want to send a single Unsolicited Neighbor Advertisement restoring the address to the original
// owner, because these packets can cause some IPv6 stacks to falsely conclude that there's an address conflict.
@@ -2532,7 +2578,7 @@ mDNSlocal void SendResponses(mDNS *const m)
if ((rr->SendRNow == intf->InterfaceID) &&
((rr->resrec.InterfaceID == mDNSInterface_Any) && !mDNSPlatformValidRecordForInterface(rr, intf)))
{
- LogInfo("SendResponses: Not sending %s, on %s", ARDisplayString(m, rr), InterfaceNameForID(m, rr->SendRNow));
+ // LogInfo("SendResponses: Not sending %s, on %s", ARDisplayString(m, rr), InterfaceNameForID(m, rr->SendRNow));
rr->SendRNow = GetNextActiveInterfaceID(intf);
}
else if (rr->SendRNow == intf->InterfaceID)
@@ -2917,10 +2963,10 @@ mDNSexport mStatus mDNS_Reconfirm_internal(mDNS *const m, CacheRecord *const rr,
// BuildQuestion puts a question into a DNS Query packet and if successful, updates the value of queryptr.
// It also appends to the list of known answer records that need to be included,
// and updates the forcast for the size of the known answer section.
-mDNSlocal mDNSBool BuildQuestion(mDNS *const m, DNSMessage *query, mDNSu8 **queryptr, DNSQuestion *q,
- CacheRecord ***kalistptrptr, mDNSu32 *answerforecast)
+mDNSlocal mDNSBool BuildQuestion(mDNS *const m, const NetworkInterfaceInfo *intf, DNSMessage *query, mDNSu8 **queryptr,
+ DNSQuestion *q, CacheRecord ***kalistptrptr, mDNSu32 *answerforecast)
{
- mDNSBool ucast = (q->LargeAnswers || q->RequestUnicast) && m->CanReceiveUnicastOn5353;
+ mDNSBool ucast = (q->LargeAnswers || q->RequestUnicast) && m->CanReceiveUnicastOn5353 && intf->SupportsUnicastMDNSResponse;
mDNSu16 ucbit = (mDNSu16)(ucast ? kDNSQClass_UnicastResponse : 0);
const mDNSu8 *const limit = query->data + NormalMaxDNSMessageData;
mDNSu8 anoninfo_space = q->AnonInfo ? AnonInfoSpace(q->AnonInfo) : 0;
@@ -3060,27 +3106,27 @@ mDNSlocal const CacheRecord *FindSPSInCache1(mDNS *const m, const DNSQuestion *c
#endif // SPC_DISABLED
}
-mDNSlocal void CheckAndSwapSPS(const CacheRecord *sps1, const CacheRecord *sps2)
+mDNSlocal void CheckAndSwapSPS(const CacheRecord **sps1, const CacheRecord **sps2)
{
const CacheRecord *swap_sps;
mDNSu32 metric1, metric2;
- if (!sps1 || !sps2) return;
- metric1 = SPSMetric(sps1->resrec.rdata->u.name.c);
- metric2 = SPSMetric(sps2->resrec.rdata->u.name.c);
- if (!SPSFeatures(sps1->resrec.rdata->u.name.c) && SPSFeatures(sps2->resrec.rdata->u.name.c) && (metric2 >= metric1))
+ if (!(*sps1) || !(*sps2)) return;
+ metric1 = SPSMetric((*sps1)->resrec.rdata->u.name.c);
+ metric2 = SPSMetric((*sps2)->resrec.rdata->u.name.c);
+ if (!SPSFeatures((*sps1)->resrec.rdata->u.name.c) && SPSFeatures((*sps2)->resrec.rdata->u.name.c) && (metric2 >= metric1))
{
- swap_sps = sps1;
- sps1 = sps2;
- sps2 = swap_sps;
+ swap_sps = *sps1;
+ *sps1 = *sps2;
+ *sps2 = swap_sps;
}
}
mDNSlocal void ReorderSPSByFeature(const CacheRecord *sps[3])
{
- CheckAndSwapSPS(sps[0], sps[1]);
- CheckAndSwapSPS(sps[0], sps[2]);
- CheckAndSwapSPS(sps[1], sps[2]);
+ CheckAndSwapSPS(&sps[0], &sps[1]);
+ CheckAndSwapSPS(&sps[0], &sps[2]);
+ CheckAndSwapSPS(&sps[1], &sps[2]);
}
@@ -3124,7 +3170,7 @@ mDNSlocal mDNSBool SuppressOnThisInterface(const DupSuppressInfo ds[DupSuppressI
return(mDNSfalse);
}
-mDNSlocal int RecordDupSuppressInfo(DupSuppressInfo ds[DupSuppressInfoSize], mDNSs32 Time, mDNSInterfaceID InterfaceID, mDNSs32 Type)
+mDNSlocal void RecordDupSuppressInfo(DupSuppressInfo ds[DupSuppressInfoSize], mDNSs32 Time, mDNSInterfaceID InterfaceID, mDNSs32 Type)
{
int i, j;
@@ -3144,8 +3190,6 @@ mDNSlocal int RecordDupSuppressInfo(DupSuppressInfo ds[DupSuppressInfoSize], mDN
ds[i].Time = Time;
ds[i].InterfaceID = InterfaceID;
ds[i].Type = Type;
-
- return(i);
}
mDNSlocal void mDNSSendWakeOnResolve(mDNS *const m, DNSQuestion *q)
@@ -3163,7 +3207,6 @@ mDNSlocal void mDNSSendWakeOnResolve(mDNS *const m, DNSQuestion *q)
// Split MAC@IPAddress and pass them separately
len = d->c[0];
- i = 1;
cnt = 0;
for (i = 1; i < len; i++)
{
@@ -3558,7 +3601,7 @@ mDNSlocal void SendQueries(mDNS *const m)
}
// If we're suppressing this question, or we successfully put it, update its SendQNow state
else if ((Suppress = SuppressOnThisInterface(q->DupSuppress, intf)) ||
- BuildQuestion(m, &m->omsg, &queryptr, q, &kalistptr, &answerforecast))
+ BuildQuestion(m, intf, &m->omsg, &queryptr, q, &kalistptr, &answerforecast))
{
// We successfully added the question to the packet. Make sure that
// we also send the NSEC3 record if required. BuildQuestion accounted for
@@ -3582,7 +3625,7 @@ mDNSlocal void SendQueries(mDNS *const m)
q->WakeOnResolveCount--;
}
- // use brackground traffic class if any included question requires it
+ // use background traffic class if any included question requires it
if (q->UseBackgroundTrafficClass)
{
useBackgroundTrafficClass = mDNStrue;
@@ -3595,7 +3638,7 @@ mDNSlocal void SendQueries(mDNS *const m)
for (ar = m->ResourceRecords; ar; ar=ar->next)
if (ar->SendRNow == intf->InterfaceID)
{
- mDNSBool ucast = (ar->ProbeCount >= DefaultProbeCountForTypeUnique-1) && m->CanReceiveUnicastOn5353;
+ mDNSBool ucast = (ar->ProbeCount >= DefaultProbeCountForTypeUnique-1) && m->CanReceiveUnicastOn5353 && intf->SupportsUnicastMDNSResponse;
mDNSu16 ucbit = (mDNSu16)(ucast ? kDNSQClass_UnicastResponse : 0);
const mDNSu8 *const limit = m->omsg.data + (m->omsg.h.numQuestions ? NormalMaxDNSMessageData : AbsoluteMaxDNSMessageData);
// We forecast: compressed name (2) type (2) class (2) TTL (4) rdlength (2) rdata (n)
@@ -3893,6 +3936,31 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
return;
}
+#if TARGET_OS_EMBEDDED
+ if ((AddRecord == QC_add) && Question_uDNS(q) && (!q->metrics.answered || (q->metrics.querySendCount > 0)))
+ {
+ uDNSMetrics * metrics;
+ const domainname * queryName;
+ mDNSu32 responseLatencyMs;
+ mDNSBool isForCellular;
+
+ metrics = &q->metrics;
+ queryName = metrics->originalQName ? metrics->originalQName : &q->qname;
+ if (metrics->querySendCount > 0)
+ {
+ responseLatencyMs = ((m->timenow - metrics->firstQueryTime) * 1000) / mDNSPlatformOneSecond;
+ }
+ else
+ {
+ responseLatencyMs = 0;
+ }
+ isForCellular = (q->qDNSServer && q->qDNSServer->cellIntf);
+
+ MetricsUpdateUDNSStats(queryName, mDNStrue, metrics->querySendCount, responseLatencyMs, isForCellular);
+ metrics->answered = mDNStrue;
+ metrics->querySendCount = 0;
+ }
+#endif
// Note: Use caution here. In the case of records with rr->DelayDelivery set, AnswerCurrentQuestionWithResourceRecord(... mDNStrue)
// may be called twice, once when the record is received, and again when it's time to notify local clients.
// If any counters or similar are added here, care must be taken to ensure that they are not double-incremented by this.
@@ -4884,7 +4952,7 @@ mDNSexport mDNSs32 mDNS_TimeNow(const mDNS *const m)
// had its Sleep Proxy client list change, and defer to actual BPF reconfiguration to mDNS_Execute().
// (GetNextScheduledEvent() returns "now" when m->SPSProxyListChanged is set)
#define SetSPSProxyListChanged(X) do { \
- if (m->SPSProxyListChanged && m->SPSProxyListChanged != (X)) mDNSPlatformUpdateProxyList(m, m->SPSProxyListChanged); \
+ if (m->SPSProxyListChanged && m->SPSProxyListChanged != (X)) mDNSPlatformUpdateProxyList(m, m->SPSProxyListChanged); \
m->SPSProxyListChanged = (X); } while(0)
// Called from mDNS_Execute() to expire stale proxy records
@@ -5558,26 +5626,34 @@ mDNSexport void mDNS_UpdateAllowSleep(mDNS *const m)
break;
}
- // Disallow sleep if there is no sleep proxy server
- const CacheRecord *cr = FindSPSInCache1(m, &intf->NetWakeBrowse, mDNSNULL, mDNSNULL);
- if ( cr == mDNSNULL)
- {
- allowSleep = mDNSfalse;
- mDNS_snprintf(reason, sizeof(reason), "No sleep proxy server on %s", intf->ifname);
- LogInfo("mDNS_UpdateAllowSleep: Sleep disabled because %s has no sleep proxy server", intf->ifname);
- break;
- }
- else if (m->SPSType != 0)
+ // If the interface can be an in-NIC Proxy, we should check if it can accomodate all the records
+ // that will be offloaded. If not, we should prevent sleep.
+ // This check will be possible once the lower layers provide an API to query the space available for offloads on the NIC.
+#if APPLE_OSX_mDNSResponder
+ if (!SupportsInNICProxy(intf))
+#endif
{
- mDNSu32 mymetric = LocalSPSMetric(m);
- mDNSu32 metric = SPSMetric(cr->resrec.rdata->u.name.c);
- if (metric >= mymetric)
+ // Disallow sleep if there is no sleep proxy server
+ const CacheRecord *cr = FindSPSInCache1(m, &intf->NetWakeBrowse, mDNSNULL, mDNSNULL);
+ if ( cr == mDNSNULL)
{
allowSleep = mDNSfalse;
- mDNS_snprintf(reason, sizeof(reason), "No sleep proxy server with better metric on %s", intf->ifname);
- LogInfo("mDNS_UpdateAllowSleep: Sleep disabled because %s has no sleep proxy server with a better metric", intf->ifname);
+ mDNS_snprintf(reason, sizeof(reason), "No sleep proxy server on %s", intf->ifname);
+ LogInfo("mDNS_UpdateAllowSleep: Sleep disabled because %s has no sleep proxy server", intf->ifname);
break;
}
+ else if (m->SPSType != 0)
+ {
+ mDNSu32 mymetric = LocalSPSMetric(m);
+ mDNSu32 metric = SPSMetric(cr->resrec.rdata->u.name.c);
+ if (metric >= mymetric)
+ {
+ allowSleep = mDNSfalse;
+ mDNS_snprintf(reason, sizeof(reason), "No sleep proxy server with better metric on %s", intf->ifname);
+ LogInfo("mDNS_UpdateAllowSleep: Sleep disabled because %s has no sleep proxy server with a better metric", intf->ifname);
+ break;
+ }
+ }
}
}
}
@@ -5608,7 +5684,7 @@ mDNSlocal mDNSBool mDNSUpdateOkToSend(mDNS *const m, AuthRecord *rr, NetworkInte
// updateid and we should have returned from above.
//
// Note: scopeid is the same as intf->InterfaceID. It is passed in so that we don't have to call the
- // platform function to extract the value from "intf" everytime.
+ // platform function to extract the value from "intf" every time.
if ((scopeid >= (sizeof(rr->updateIntID) * mDNSNBBY) || bit_get_opaque64(rr->updateIntID, scopeid)) &&
(!rr->resrec.InterfaceID || rr->resrec.InterfaceID == intf->InterfaceID))
@@ -5619,35 +5695,41 @@ mDNSlocal mDNSBool mDNSUpdateOkToSend(mDNS *const m, AuthRecord *rr, NetworkInte
mDNSexport void UpdateRMACCallback(mDNS *const m, void *context)
{
- IPAddressMACMapping *addrmap = (IPAddressMACMapping *)context ;
- m->CurrentRecord = m->ResourceRecords;
-
- if (!addrmap)
- {
- LogMsg("UpdateRMACCallback: Address mapping is NULL");
- return;
- }
-
- while (m->CurrentRecord)
- {
- AuthRecord *rr = m->CurrentRecord;
- // If this is a keepalive record and the remote IP address matches, update the RData
- if (mDNS_KeepaliveRecord(&rr->resrec))
- {
- mDNSAddr raddr;
- getKeepaliveRaddr(m, rr, &raddr);
- if (mDNSSameAddress(&raddr, &addrmap->ipaddr))
- {
- UpdateKeepaliveRData(m, rr, mDNSNULL, mDNStrue, (char *)(addrmap->ethaddr));
- }
- }
- m->CurrentRecord = rr->next;
- }
-
- if (addrmap)
- {
- mDNSPlatformMemFree(addrmap);
- }
+ IPAddressMACMapping *addrmap = (IPAddressMACMapping *)context ;
+ m->CurrentRecord = m->ResourceRecords;
+
+ if (!addrmap)
+ {
+ LogMsg("UpdateRMACCallback: Address mapping is NULL");
+ return;
+ }
+
+ while (m->CurrentRecord)
+ {
+ AuthRecord *rr = m->CurrentRecord;
+ // If this is a non-sleep proxy keepalive record and the remote IP address matches, update the RData
+ if (!rr->WakeUp.HMAC.l[0] && mDNS_KeepaliveRecord(&rr->resrec))
+ {
+ mDNSAddr raddr;
+ getKeepaliveRaddr(m, rr, &raddr);
+ if (mDNSSameAddress(&raddr, &addrmap->ipaddr))
+ {
+ // Update the MAC address only if it is not a zero MAC address
+ mDNSEthAddr macAddr;
+ mDNSu8 *ptr = GetValueForMACAddr((mDNSu8 *)(addrmap->ethaddr), (mDNSu8 *) (addrmap->ethaddr + sizeof(addrmap->ethaddr)), &macAddr);
+ if (ptr != mDNSNULL && !mDNSEthAddressIsZero(macAddr))
+ {
+ UpdateKeepaliveRData(m, rr, mDNSNULL, mDNStrue, (char *)(addrmap->ethaddr));
+ }
+ }
+ }
+ m->CurrentRecord = rr->next;
+ }
+
+ if (addrmap)
+ {
+ mDNSPlatformMemFree(addrmap);
+ }
}
mDNSexport mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkInterfaceInfo *const intf, mDNSBool updateMac, char *ethAddr)
@@ -6114,29 +6196,49 @@ mDNSexport mDNSBool mDNSCoreHaveAdvertisedMulticastServices(mDNS *const m)
return mDNSfalse;
}
+#define WAKE_ONLY_SERVICE 1
+#define AC_ONLY_SERVICE 2
+
#ifdef APPLE_OSX_mDNSResponder
-// This function is used only in the case of local NIC proxy. For external
-// sleep proxy server, we do this in SPSInitRecordsBeforeUpdate when we
-// walk the resource records.
-mDNSlocal void SendGoodbyesForWakeOnlyService(mDNS *const m, mDNSBool *WakeOnlyService)
+mDNSlocal void SendGoodbyesForSelectServices(mDNS *const m, mDNSBool *servicePresent, mDNSu32 serviceType)
{
AuthRecord *rr;
-
- *WakeOnlyService = mDNSfalse;
+ *servicePresent = mDNSfalse;
// Mark all the records we need to deregister and send them
for (rr = m->ResourceRecords; rr; rr=rr->next)
{
- if ((rr->AuthFlags & AuthFlagsWakeOnly) &&
- rr->resrec.RecordType == kDNSRecordTypeShared && rr->RequireGoodbye)
+ // If the service type is wake only service and the auth flags match and requires a goodbye
+ // OR if the service type is AC only and it is not a keepalive record,
+ // mark the records we need to deregister and send them
+ if ((serviceType == WAKE_ONLY_SERVICE && (rr->AuthFlags & AuthFlagsWakeOnly) &&
+ rr->resrec.RecordType == kDNSRecordTypeShared && rr->RequireGoodbye) ||
+ (serviceType == AC_ONLY_SERVICE && !mDNS_KeepaliveRecord(&rr->resrec)))
{
rr->ImmedAnswer = mDNSInterfaceMark;
- *WakeOnlyService = mDNStrue;
+ *servicePresent = mDNStrue;
}
}
}
+#endif
+
+#ifdef APPLE_OSX_mDNSResponder
+// This function is used only in the case of local NIC proxy. For external
+// sleep proxy server, we do this in SPSInitRecordsBeforeUpdate when we
+// walk the resource records.
+mDNSlocal void SendGoodbyesForWakeOnlyService(mDNS *const m, mDNSBool *WakeOnlyService)
+{
+ return SendGoodbyesForSelectServices(m, WakeOnlyService, WAKE_ONLY_SERVICE);
+}
#endif // APPLE_OSx_mDNSResponder
+#ifdef APPLE_OSX_mDNSResponder
+mDNSlocal void SendGoodbyesForACOnlyServices(mDNS *const m, mDNSBool *acOnlyService)
+{
+ return SendGoodbyesForSelectServices(m, acOnlyService, AC_ONLY_SERVICE);
+}
+#endif
+
mDNSlocal void SendSleepGoodbyes(mDNS *const m, mDNSBool AllInterfaces, mDNSBool unicast)
{
AuthRecord *rr;
@@ -6232,6 +6334,7 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
{
mDNSBool SendGoodbyes = mDNStrue;
mDNSBool WakeOnlyService = mDNSfalse;
+ mDNSBool ACOnlyService = mDNSfalse;
mDNSBool invokeKACallback = mDNStrue;
const CacheRecord *sps[3] = { mDNSNULL };
mDNSOpaque64 updateIntID = zeroOpaque64;
@@ -6288,9 +6391,12 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
#if APPLE_OSX_mDNSResponder
else if (SupportsInNICProxy(intf))
{
- if (ActivateLocalProxy(m, intf) == mStatus_NoError)
+ mDNSBool keepaliveOnly = mDNSfalse;
+ if (ActivateLocalProxy(m, intf, &keepaliveOnly) == mStatus_NoError)
{
SendGoodbyesForWakeOnlyService(m, &WakeOnlyService);
+ if (keepaliveOnly)
+ SendGoodbyesForACOnlyServices(m, &ACOnlyService);
SendGoodbyes = mDNSfalse;
invokeKACallback = mDNSfalse;
LogSPS("BeginSleepProcessing: %-6s using local proxy", intf->ifname);
@@ -6334,9 +6440,9 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
{
#if ForceAlerts
if (intf->SPSAddr[i].type)
- { LogMsg("BeginSleepProcessing: %s %d intf->SPSAddr[i].type %d", intf->ifname, i, intf->SPSAddr[i].type); *(long*)0 = 0; }
+ LogFatalError("BeginSleepProcessing: %s %d intf->SPSAddr[i].type %d", intf->ifname, i, intf->SPSAddr[i].type);
if (intf->NetWakeResolve[i].ThisQInterval >= 0)
- { LogMsg("BeginSleepProcessing: %s %d intf->NetWakeResolve[i].ThisQInterval %d", intf->ifname, i, intf->NetWakeResolve[i].ThisQInterval); *(long*)0 = 0; }
+ LogFatalError("BeginSleepProcessing: %s %d intf->NetWakeResolve[i].ThisQInterval %d", intf->ifname, i, intf->NetWakeResolve[i].ThisQInterval);
#endif
intf->SPSAddr[i].type = mDNSAddrType_None;
if (intf->NetWakeResolve[i].ThisQInterval >= 0) mDNS_StopQuery(m, &intf->NetWakeResolve[i]);
@@ -6396,10 +6502,10 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
LogSPS("BeginSleepProcessing: Not registering with Sleep Proxy Server on all interfaces");
SendSleepGoodbyes(m, mDNSfalse, mDNSfalse);
}
- else if (WakeOnlyService)
+ else if (WakeOnlyService || ACOnlyService)
{
// If we saw WakeOnly service above, send the goodbyes now.
- LogSPS("BeginSleepProcessing: Sending goodbyes for WakeOnlyServices");
+ LogSPS("BeginSleepProcessing: Sending goodbyes for %s", WakeOnlyService? "WakeOnlyService" : "AC Only Service");
SendResponses(m);
}
}
@@ -6473,11 +6579,7 @@ mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleep)
{
m->SleepState = SleepState_Awake;
m->SleepSeqNum++;
- // If the machine wakes and then immediately tries to sleep again (e.g. a maintenance wake)
- // then we enforce a minimum delay of 16 seconds before we begin sleep processing.
- // This is to allow time for the Ethernet link to come up, DHCP to get an address, mDNS to issue queries, etc.,
- // before we make our determination of whether there's a Sleep Proxy out there we should register with.
- m->DelaySleep = NonZeroTime(m->timenow + mDNSPlatformOneSecond * 16);
+ m->DelaySleep = 0;
}
if (m->SPSState == 3)
@@ -7103,7 +7205,7 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
const mDNSAddr *srcaddr, const mDNSInterfaceID InterfaceID, mDNSBool LegacyQuery, mDNSBool QueryWasMulticast,
mDNSBool QueryWasLocalUnicast, DNSMessage *const response)
{
- mDNSBool FromLocalSubnet = srcaddr && mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr, mDNSNULL);
+ mDNSBool FromLocalSubnet = srcaddr && mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr);
AuthRecord *ResponseRecords = mDNSNULL;
AuthRecord **nrp = &ResponseRecords;
@@ -7653,9 +7755,9 @@ exit:
DNSQuestion *q = DupQuestions;
DupQuestions = q->NextInDQList;
q->NextInDQList = mDNSNULL;
- i = RecordDupSuppressInfo(q->DupSuppress, m->timenow, InterfaceID, srcaddr->type);
- debugf("ProcessQuery: Recorded DSI for %##s (%s) on %p/%s %d", q->qname.c, DNSTypeName(q->qtype), InterfaceID,
- srcaddr->type == mDNSAddrType_IPv4 ? "v4" : "v6", i);
+ RecordDupSuppressInfo(q->DupSuppress, m->timenow, InterfaceID, srcaddr->type);
+ debugf("ProcessQuery: Recorded DSI for %##s (%s) on %p/%s", q->qname.c, DNSTypeName(q->qtype), InterfaceID,
+ srcaddr->type == mDNSAddrType_IPv4 ? "v4" : "v6");
}
if (McastNSEC3Records)
@@ -7673,7 +7775,7 @@ mDNSlocal void mDNSCoreReceiveQuery(mDNS *const m, const DNSMessage *const msg,
{
mDNSu8 *responseend = mDNSNULL;
mDNSBool QueryWasLocalUnicast = srcaddr && dstaddr &&
- !mDNSAddrIsDNSMulticast(dstaddr) && mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr, mDNSNULL);
+ !mDNSAddrIsDNSMulticast(dstaddr) && mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr);
if (!InterfaceID && dstaddr && mDNSAddrIsDNSMulticast(dstaddr))
{
@@ -7791,111 +7893,6 @@ mDNSlocal DNSQuestion *ExpectingUnicastResponseForRecord(mDNS *const m,
return(mDNSNULL);
}
-// Return a pointer to the primary service name, skipping subtype name if present.
-mDNSlocal const domainname *getPrimaryServiceName(const domainname *domainName)
-{
- const domainname *primaryName = domainName;
- const domainname *subName = SkipLeadingLabels(domainName, 1);
-
- if (SameDomainLabel(subName->c, (const mDNSu8 *)mDNSSubTypeLabel))
- {
- // skip "<sub type name>._sub" portion of name
- primaryName = SkipLeadingLabels(domainName, 2);
- debugf("getPrimaryServiceName: returning %##s for _sub type", primaryName);
- }
-
- return primaryName;
-}
-
-// This function is not called if the packet is from us, which implies that we accept all multicast packets coming from us.
-mDNSlocal mDNSBool ExpectingMulticastResponseForRecord(mDNS *const m, CacheRecord *rr, const mDNSAddr *srcaddr, mDNSBool recordAccepted,
- CacheRecord **McastNSEC3Records)
-{
- DNSQuestion *q;
-
- // Accept A and AAAA if we accepted something before in the same packet as most likely related to the
- // service records that we may have accepted.
- if (recordAccepted && (rr->resrec.rrtype == kDNSType_A || rr->resrec.rrtype == kDNSType_AAAA))
- {
- LogInfo("ExpectingMulticastResponseForRecord:A:AAAA: accepting %s, from %#a due to same packet %d", CRDisplayString(m, rr), srcaddr, m->PktNum);
- return mDNStrue;
- }
- for (q = m->Questions; q; q=q->next)
- {
- if (!q->DuplicateOf && mDNSOpaque16IsZero(q->TargetQID))
- {
- mDNSBool ret;
- // 1. If a resource record answers question, cache it. This also will cache NSECs if it asserts
- // non-existence of q->qtype. If we have any matching NSEC3 Records for the question, send
- // it along with the resource record. Do it only for questions that are expecting to
- // discover only its peers (q->AnonInfo not NULL)
- if (q->AnonInfo && McastNSEC3Records && !rr->resrec.AnonInfo)
- {
- InitializeAnonInfoForCR(m, McastNSEC3Records, rr);
- }
- ret = ResourceRecordAnswersQuestion(&rr->resrec, q);
- if (ret)
- {
- // The record and the question belong to the same subset. Set the
- // anonymous data in the cache record.
- if (q->AnonInfo && rr->resrec.AnonInfo)
- {
- SetAnonData(q, &rr->resrec, mDNSfalse);
- }
- LogInfo("ExpectingMulticastResponseForRecord: Name and Type match, accepting %s, from %#a", CRDisplayString(m, rr), srcaddr);
- if (rr->resrec.rrtype == kDNSType_NSEC)
- LogInfo("ExpectingMulticastResponseForRecord: record %s, question %##s (%s)", CRDisplayString(m, rr), q->qname.c, DNSTypeName(q->qtype));
- return mDNStrue;
- }
- if (rr->resrec.rrtype == kDNSType_SRV || rr->resrec.rrtype == kDNSType_TXT)
- {
- // Point to the service type in the record name
- const domainname *name = SkipLeadingLabels(rr->resrec.name, 1);
-
- // If question is for a sub type, just compare against the primary service type
- const domainname *primaryName = getPrimaryServiceName(&q->qname);
-
- // 2. If the SRV or TXT record matches the service name, then cache it. If the TXT or SRV record is
- // before the PTR record in the packet, PTR record may not be in the cache yet and hence the logic
- // in (3) below will fail to cache it.
- if (q->qtype == kDNSType_PTR && name && SameDomainName(primaryName, name))
- {
- LogInfo("ExpectingMulticastResponseForRecord: Accepting %s due to PTR match, question %##s from %#a, pktnum %d",
- CRDisplayString(m, rr), q->qname.c, srcaddr, m->PktNum);
- return mDNStrue;
- }
-
- if (name)
- {
- const mDNSu32 slot = HashSlot(name);
- const mDNSu32 namehash = DomainNameHashValue(name);
- CacheGroup *cg = CacheGroupForName(m, slot, namehash, name);
- CacheRecord *cr;
-
- // 3. Same as in (2), but look in the cache in case we don't have the PTR question.
-
- for (cr = cg ? cg->members : mDNSNULL; cr; cr=cr->next)
- {
- if (cr->resrec.rrtype == kDNSType_PTR)
- {
- primaryName = getPrimaryServiceName(cr->resrec.name);
-
- if (SameDomainName(primaryName, name))
- {
- LogInfo("ExpectingMulticastResponseForRecord: accepting %s, from %#a, pktnum %d",
- CRDisplayString(m, rr), srcaddr, m->PktNum);
- return mDNStrue;
- }
- }
- }
- }
- }
- }
- }
- debugf("ExpectingMulticastResponseForRecord: discarding %s, from %#a, pktnum %d", CRDisplayString(m, rr), srcaddr, m->PktNum);
- return(mDNSfalse);
-}
-
// Certain data types need more space for in-memory storage than their in-packet rdlength would imply
// Currently this applies only to rdata types containing more than one domainname,
// or types where the domainname is not the last item in the structure.
@@ -8441,7 +8438,8 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
name = (const domainname *)(name->c + 1 + name->c[0]);
hash = DomainNameHashValue(name);
slot = HashSlot(name);
- cg = CacheGroupForName(m, slot, hash, name);
+ // For now, we don't need to update cg here, because we'll do it again immediately, back up at the start of this loop
+ //cg = CacheGroupForName(m, slot, hash, name);
}
}
}
@@ -8643,7 +8641,7 @@ mDNSlocal CacheRecord* mDNSCoreReceiveCacheCheck(mDNS *const m, const DNSMessage
mDNSlocal void mDNSParseNSEC3Records(mDNS *const m, const DNSMessage *const response, const mDNSu8 *end,
const mDNSInterfaceID InterfaceID, CacheRecord **NSEC3Records)
{
- const mDNSu8 *ptr = response->data;
+ const mDNSu8 *ptr;
CacheRecord *rr;
int i;
@@ -8692,24 +8690,6 @@ mDNSlocal void mDNSCoreResetRecord(mDNS *const m)
}
}
-#define DEVICE_INFO_RECORD_LABELS 4
-
-// Determine if the record is an instance of _device-info._tcp.local.
-mDNSlocal mDNSBool IsDeviceInfoRecord(const domainname *d)
-{
- const domainname *afterInstance;
-
- if (CountLabels(d) != DEVICE_INFO_RECORD_LABELS)
- return mDNSfalse;
-
- // skip the instance name
- afterInstance = SkipLeadingLabels(d, 1);
- if (SameDomainName(afterInstance, &LocalDeviceInfoName))
- return mDNStrue;
-
- return mDNSfalse;
-}
-
// Note: mDNSCoreReceiveResponse calls mDNS_Deregister_internal which can call a user callback, which may change
// the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
@@ -8722,9 +8702,8 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
const mDNSInterfaceID InterfaceID)
{
int i;
- mDNSBool myself;
mDNSBool ResponseMCast = dstaddr && mDNSAddrIsDNSMulticast(dstaddr);
- mDNSBool ResponseSrcLocal = !srcaddr || mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr, &myself);
+ mDNSBool ResponseSrcLocal = !srcaddr || mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr);
DNSQuestion *llqMatch = mDNSNULL;
DNSQuestion *unicastQuestion = mDNSNULL;
uDNS_LLQType LLQType = uDNS_recvLLQResponse(m, response, end, srcaddr, srcport, &llqMatch);
@@ -8742,12 +8721,11 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
mDNSu8 rcode = '\0';
mDNSBool rrsigsCreated = mDNSfalse;
mDNSBool DNSSECQuestion = mDNSfalse;
- mDNSBool recordAccepted = mDNSfalse;
NetworkInterfaceInfo *llintf = FirstIPv4LLInterfaceForID(m, InterfaceID);
// 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
+ // security, e.g. DNSSEC., not worrying about which section in the spoof packet contained the record.
int firstauthority = response->h.numAnswers;
int firstadditional = firstauthority + response->h.numAuthorities;
int totalrecords = firstadditional + response->h.numAdditionals;
@@ -8983,64 +8961,69 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
// Even though it is AcceptableResponse, we still need a DNSServer pointer for the resource records that
// we create.
- if (!mDNSOpaque16IsZero(response->h.id))
- {
- DNSQuestion *q = ExpectingUnicastResponseForRecord(m, srcaddr, ResponseSrcLocal, dstport, response->h.id, &m->rec.r, !dstaddr);
-
- // Initialize the DNS server on the resource record which will now filter what questions we answer with
- // this record.
- //
- // We could potentially lookup the DNS server based on the source address, but that may not work always
- // and that's why ExpectingUnicastResponseForRecord does not try to verify whether the response came
- // from the DNS server that queried. We follow the same logic here. If we can find a matching quetion based
- // on the "id" and "source port", then this response answers the question and assume the response
- // came from the same DNS server that we sent the query to.
-
- if (q != mDNSNULL)
- {
- AcceptableResponse = mDNStrue;
- if (!InterfaceID)
- {
- debugf("mDNSCoreReceiveResponse: InterfaceID %p %##s (%s)", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
- m->rec.r.resrec.rDNSServer = uDNSServer = q->qDNSServer;
- }
- else
- LogInfo("mDNSCoreReceiveResponse: InterfaceID %p %##s (%s)", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
- }
- else
- {
- // If we can't find a matching question, we need to see whether we have seen records earlier that matched
- // the question. The code below does that. So, make this record unacceptable for now
- if (!InterfaceID)
- {
- debugf("mDNSCoreReceiveResponse: Can't find question for record name %##s", m->rec.r.resrec.name->c);
- AcceptableResponse = mDNSfalse;
- }
- }
- }
- else if (ExpectingMulticastResponseForRecord(m, &m->rec.r, srcaddr, recordAccepted, &McastNSEC3Records))
- {
- recordAccepted = mDNStrue;
- AcceptableResponse = mDNStrue;
- LogInfo("mDNSCoreReceiveResponse: Accepting record in response to QU question %s, InterfaceID %p", CRDisplayString(m, &m->rec.r),
- InterfaceID);
- }
- else if (IsDeviceInfoRecord(m->rec.r.resrec.name))
- {
- recordAccepted = mDNStrue;
- AcceptableResponse = mDNStrue;
- LogInfo("mDNSCoreReceiveResponse: Accepting _device-info record %s, InterfaceID %p",
- CRDisplayString(m, &m->rec.r), InterfaceID);
- }
+ DNSQuestion *q = ExpectingUnicastResponseForRecord(m, srcaddr, ResponseSrcLocal, dstport, response->h.id, &m->rec.r, !dstaddr);
+
+ // Initialize the DNS server on the resource record which will now filter what questions we answer with
+ // this record.
+ //
+ // We could potentially lookup the DNS server based on the source address, but that may not work always
+ // and that's why ExpectingUnicastResponseForRecord does not try to verify whether the response came
+ // from the DNS server that queried. We follow the same logic here. If we can find a matching quetion based
+ // on the "id" and "source port", then this response answers the question and assume the response
+ // came from the same DNS server that we sent the query to.
+
+ if (q != mDNSNULL)
+ {
+ AcceptableResponse = mDNStrue;
+ if (!InterfaceID)
+ {
+ debugf("mDNSCoreReceiveResponse: InterfaceID %p %##s (%s)", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
+ m->rec.r.resrec.rDNSServer = uDNSServer = q->qDNSServer;
+ }
+ else
+ LogInfo("mDNSCoreReceiveResponse: InterfaceID %p %##s (%s)", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
+ }
+ else
+ {
+ // If we can't find a matching question, we need to see whether we have seen records earlier that matched
+ // the question. The code below does that. So, make this record unacceptable for now
+ if (!InterfaceID)
+ {
+ debugf("mDNSCoreReceiveResponse: Can't find question for record name %##s", m->rec.r.resrec.name->c);
+ AcceptableResponse = mDNSfalse;
+ }
+ }
}
}
else if (llintf && llintf->IgnoreIPv4LL && m->rec.r.resrec.rrtype == kDNSType_A)
{
- CacheRecord *const rr = &m->rec.r;
- RDataBody2 *const rdb = (RDataBody2 *)rr->smallrdatastorage.data;
+ // There are some routers (rare, thankfully) that generate bogus ARP responses for
+ // any IPv4 address they don’t recognize, including RFC 3927 IPv4 link-local addresses.
+ // To work with these broken routers, client devices need to blacklist these broken
+ // routers and ignore their bogus ARP responses. Some devices implement a technique
+ // such as the one described in US Patent 7436783, which lets clients detect and
+ // ignore these broken routers: <https://www.google.com/patents/US7436783>
+
+ // OS X and iOS do not implement this defensive mechanism, instead taking a simpler
+ // approach of just detecting these broken routers and completely disabling IPv4
+ // link-local communication on interfaces where a broken router is detected.
+ // OS X and iOS set the IFEF_ARPLL interface flag on interfaces
+ // that are deemed “safe” for IPv4 link-local communication;
+ // the flag is cleared on interfaces where a broken router is detected.
+
+ // OS X and iOS will not even try to communicate with an IPv4
+ // link-local destination on an interface without the IFEF_ARPLL flag set.
+ // This can cause some badly written applications to freeze for a long time if they
+ // attempt to connect to an IPv4 link-local destination address and then wait for
+ // that connection attempt to time out before trying other candidate addresses.
+
+ // To mask this client bug, we suppress acceptance of IPv4 link-local address
+ // records on interfaces where we know the OS will be unwilling even to attempt
+ // communication with those IPv4 link-local destination addresses.
+ // <rdar://problem/9400639> kSuppress IPv4LL answers on interfaces without IFEF_ARPLL
- // If we are supposed to ignore link-local addresses on this interface, drop
- // all "A" records that have link-local address in them.
+ const CacheRecord *const rr = &m->rec.r;
+ const RDataBody2 *const rdb = (RDataBody2 *)rr->smallrdatastorage.data;
if (mDNSv4AddressIsLinkLocal(&rdb->ipv4))
{
LogInfo("mDNSResponder: Dropping LinkLocal packet %s", CRDisplayString(m, &m->rec.r));
@@ -9099,7 +9082,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
if (rr->ProbeCount > DefaultProbeCountForTypeUnique)
LogInfo("mDNSCoreReceiveResponse: Already reset to Probing: %s", ARDisplayString(m, rr));
else if (rr->ProbeCount == DefaultProbeCountForTypeUnique)
- LogMsg("mDNSCoreReceiveResponse: Ignoring response received before we even began probing: %s", ARDisplayString(m, rr));
+ LogInfo("mDNSCoreReceiveResponse: Ignoring response received before we even began probing: %s", ARDisplayString(m, rr));
else
{
LogMsg("mDNSCoreReceiveResponse: Received from %#a:%d %s", srcaddr, mDNSVal16(srcport), CRDisplayString(m, &m->rec.r));
@@ -9185,27 +9168,6 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
rr = mDNSCoreReceiveCacheCheck(m, response, LLQType, slot, cg, unicastQuestion, &cfp, &NSECCachePtr, InterfaceID);
}
- // If mDNSOppCaching is set (which affects only multicast), enable opportunistic caching in which case we cache
- // everything that was received over multicast. Otherwise, we are selective about the caching.
- //
- // Cache everything that is from ourselves (that's how we answer any questions looking for them). Otherwise call
- // ExpectingMulticastResponseForRecord which decides whether to cache this record or not.
- //
- if (!m->mDNSOppCaching && !rr && !myself && mDNSOpaque16IsZero(response->h.id))
- {
- if (!ExpectingMulticastResponseForRecord(m, &m->rec.r, srcaddr, recordAccepted, &McastNSEC3Records))
- {
- //LogMsg("mDNSCoreReceiveResponse: discarding %s", CRDisplayString(m, &m->rec.r));
- mDNSCoreResetRecord(m);
- continue;
- }
- else
- {
- recordAccepted = mDNStrue;
- }
- }
-
-
// If packet resource record not in our cache, add it now
// (unless it is just a deletion of a record we never had, in which case we don't care)
if (!rr && m->rec.r.resrec.rroriginalttl > 0)
@@ -9343,15 +9305,22 @@ exit:
// goodbye announcement with the cache flush bit set (or a case-change on record rdata,
// which we treat as a goodbye followed by an addition) and in that case it would be
// inappropriate to synchronize all the other records to a TTL of 0 (or 1).
+
// We suppress the message for the specific case of correcting from 240 to 60 for type TXT,
// because certain early Bonjour devices are known to have this specific mismatch, and
// there's no point filling syslog with messages about something we already know about.
// We also don't log this for uDNS responses, since a caching name server is obliged
// to give us an aged TTL to correct for how long it has held the record,
// so our received TTLs are expected to vary in that case
+
+ // We also suppress log message in the case of SRV records that are recieved
+ // with a TTL of 4500 that are already cached with a TTL of 120 seconds, since
+ // this behavior was observed for a number of discoveryd based AppleTV's in iOS 8
+ // GM builds.
if (r2->resrec.rroriginalttl != r1->resrec.rroriginalttl && r1->resrec.rroriginalttl > 1)
{
if (!(r2->resrec.rroriginalttl == 240 && r1->resrec.rroriginalttl == 60 && r2->resrec.rrtype == kDNSType_TXT) &&
+ !(r2->resrec.rroriginalttl == 120 && r1->resrec.rroriginalttl == 4500 && r2->resrec.rrtype == kDNSType_SRV) &&
mDNSOpaque16IsZero(response->h.id))
LogInfo("Correcting TTL from %4d to %4d for %s",
r2->resrec.rroriginalttl, r1->resrec.rroriginalttl, CRDisplayString(m, r2));
@@ -9550,6 +9519,11 @@ mDNSlocal mDNSu8 *GetValueForMACAddr(mDNSu8 *ptr, mDNSu8 *limit, mDNSEthAddr *et
}
else if (*ptr == ':')
{
+ if (colons >=5 || val > 255)
+ {
+ LogMsg("GetValueForMACAddr: Address malformed colons %d val %d", colons, val);
+ return mDNSNULL;
+ }
eth->b[colons] = val;
colons++;
val = 0;
@@ -9681,6 +9655,11 @@ mDNSlocal mDNSu8 *GetValueForIPv4Addr(mDNSu8 *ptr, mDNSu8 *limit, mDNSv4Addr *v4
val = val * 10 + *ptr - '0';
else if (*ptr == '.')
{
+ if (val > 255 || dots >= 3)
+ {
+ LogMsg("GetValueForIPv4Addr: something wrong ptr(%p) %c, limit %p, dots %d", ptr, *ptr, limit, dots);
+ return mDNSNULL;
+ }
v4->b[dots++] = val;
val = 0;
}
@@ -9723,6 +9702,37 @@ mDNSlocal mDNSu8 *GetValueForKeepalive(mDNSu8 *ptr, mDNSu8 *limit, mDNSu32 *valu
return ptr;
}
+mDNSexport mDNSBool mDNSValidKeepAliveRecord(AuthRecord *rr)
+{
+ mDNSAddr laddr, raddr;
+ mDNSEthAddr eth;
+ mDNSIPPort lport, rport;
+ mDNSu32 timeout, seq, ack;
+ mDNSu16 win;
+
+ if (!mDNS_KeepaliveRecord(&rr->resrec))
+ {
+ return mDNSfalse;
+ }
+
+ timeout = seq = ack = 0;
+ win = 0;
+ laddr = raddr = zeroAddr;
+ lport = rport = zeroIPPort;
+
+ mDNS_ExtractKeepaliveInfo(rr, &timeout, &laddr, &raddr, &eth, &seq, &ack, &lport, &rport, &win);
+
+ if (mDNSAddressIsZero(&laddr) || mDNSIPPortIsZero(lport) ||
+ mDNSAddressIsZero(&raddr) || mDNSIPPortIsZero(rport) ||
+ mDNSEthAddressIsZero(eth))
+ {
+ return mDNSfalse;
+ }
+
+ return mDNStrue;
+}
+
+
mDNSlocal void mDNS_ExtractKeepaliveInfo(AuthRecord *ar, mDNSu32 *timeout, mDNSAddr *laddr, mDNSAddr *raddr, mDNSEthAddr *eth, mDNSu32 *seq,
mDNSu32 *ack, mDNSIPPort *lport, mDNSIPPort *rport, mDNSu16 *win)
{
@@ -9899,16 +9909,18 @@ mDNSlocal void mDNS_SendKeepalives(mDNS *const m)
mDNSlocal void mDNS_SendKeepaliveACK(mDNS *const m, AuthRecord *ar)
{
- if (ar != mDNSNULL)
- {
- LogInfo("mDNS_SendKeepalivesACK: AuthRecord is NULL");
- return;
- }
- mDNSu32 timeout, seq, ack;
+ mDNSu32 timeout, seq, ack, seqInc;
mDNSu16 win;
mDNSAddr laddr, raddr;
mDNSEthAddr eth;
mDNSIPPort lport, rport;
+ mDNSu8 *ptr;
+
+ if (ar == mDNSNULL)
+ {
+ LogInfo("mDNS_SendKeepalivesACK: AuthRecord is NULL");
+ return;
+ }
timeout = seq = ack = 0;
win = 0;
@@ -9923,6 +9935,17 @@ mDNSlocal void mDNS_SendKeepaliveACK(mDNS *const m, AuthRecord *ar)
LogInfo("mDNS_SendKeepaliveACK: not a valid record %s for keepalive", ARDisplayString(m, ar));
return;
}
+
+ // To send a keepalive ACK, we need to add one to the sequence number from the keepalive
+ // record, which is the TCP connection's "next" sequence number minus one. Otherwise, the
+ // keepalive ACK also ends up being a keepalive probe. Also, seq is in network byte order, so
+ // it's converted to host byte order before incrementing it by one.
+ ptr = (mDNSu8 *)&seq;
+ seqInc = (mDNSu32)((ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]) + 1;
+ ptr[0] = (mDNSu8)((seqInc >> 24) & 0xFF);
+ ptr[1] = (mDNSu8)((seqInc >> 16) & 0xFF);
+ ptr[2] = (mDNSu8)((seqInc >> 8) & 0xFF);
+ ptr[3] = (mDNSu8)((seqInc ) & 0xFF);
LogMsg("mDNS_SendKeepaliveACK: laddr %#a raddr %#a lport %d rport %d", &laddr, &raddr, mDNSVal16(lport), mDNSVal16(rport));
mDNSPlatformSendKeepalive(&laddr, &raddr, &lport, &rport, seq, ack, win);
}
@@ -10089,6 +10112,8 @@ mDNSlocal void mDNSCoreReceiveUpdateR(mDNS *const m, const DNSMessage *const msg
{
mDNSu32 updatelease = 60 * 60; // If SPS fails to indicate lease time, assume one hour
const mDNSu8 *ptr = LocateOptRR(msg, end, DNSOpt_LeaseData_Space);
+ mDNSAddr spsaddr;
+ char *ifname;
if (ptr)
{
ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
@@ -10138,8 +10163,7 @@ mDNSlocal void mDNSCoreReceiveUpdateR(mDNS *const m, const DNSMessage *const msg
}
// Update the dynamic store with the IP Address and MAC address of the sleep proxy
- char *ifname = InterfaceNameForID(m, InterfaceID);
- mDNSAddr spsaddr;
+ ifname = InterfaceNameForID(m, InterfaceID);
mDNSPlatformMemCopy(&spsaddr, srcaddr, sizeof (mDNSAddr));
mDNSPlatformStoreSPSMACAddr(&spsaddr, ifname);
}
@@ -10152,12 +10176,7 @@ mDNSexport void MakeNegativeCacheRecord(mDNS *const m, CacheRecord *const cr,
const domainname *const name, const mDNSu32 namehash, const mDNSu16 rrtype, const mDNSu16 rrclass, mDNSu32 ttl_seconds, mDNSInterfaceID InterfaceID, DNSServer *dnsserver)
{
if (cr == &m->rec.r && m->rec.r.resrec.RecordType)
- {
- LogMsg("MakeNegativeCacheRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
-#if ForceAlerts
- *(long*)0 = 0;
-#endif
- }
+ LogFatalError("MakeNegativeCacheRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
// Create empty resource record
cr->resrec.RecordType = kDNSRecordTypePacketNegative;
@@ -10265,7 +10284,7 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, void *const pkt, const mDNSu8 *co
// Track the number of multicast packets received from a source outside our subnet.
// Check the destination address to avoid accounting for spurious packets that
// comes in with message id zero.
- if (!mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr, mDNSNULL) &&
+ if (!mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr) &&
mDNSAddressIsAllDNSLinkGroup(dstaddr))
{
m->RemoteSubnet++;
@@ -10472,8 +10491,8 @@ mDNSexport McastResolver *mDNS_AddMcastResolver(mDNS *const m, const domainname
{
if ((*p)->interface == interface && SameDomainName(&(*p)->domain, d))
{
- if (!((*p)->flags & DNSServer_FlagDelete)) LogMsg("Note: Mcast Resolver domain %##s (%p) registered more than once", d->c, interface);
- (*p)->flags &= ~DNSServer_FlagDelete;
+ if (!((*p)->flags & McastResolver_FlagDelete)) LogMsg("Note: Mcast Resolver domain %##s (%p) registered more than once", d->c, interface);
+ (*p)->flags &= ~McastResolver_FlagDelete;
tmp = *p;
*p = tmp->next;
tmp->next = mDNSNULL;
@@ -10491,7 +10510,7 @@ mDNSexport McastResolver *mDNS_AddMcastResolver(mDNS *const m, const domainname
else
{
(*p)->interface = interface;
- (*p)->flags = DNSServer_FlagNew;
+ (*p)->flags = McastResolver_FlagNew;
(*p)->timeout = timeout;
AssignDomainName(&(*p)->domain, d);
(*p)->next = mDNSNULL;
@@ -10696,10 +10715,11 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
// match the scoped entries by mistake.
//
// Note: DNS configuration change will help pick the new dns servers but currently it does not affect the timeout
-
- if (curr->scoped && curr->interface == mDNSInterface_Any)
+
+ // Skip DNSServers that are InterfaceID Scoped but have no valid interfaceid set OR DNSServers that are ServiceID Scoped but have no valid serviceid set
+ if ((curr->scoped == kScopeInterfaceID && curr->interface == mDNSInterface_Any) || (curr->scoped == kScopeServiceID && curr->serviceID <= 0))
{
- debugf("SetValidDNSServers: Scoped DNS server %#a (Domain %##s) with Interface Any", &curr->addr, curr->domain.c);
+ LogInfo("SetValidDNSServers: ScopeType[%d] Skipping DNS server %#a (Domain %##s) Interface:[%p] Serviceid:[%d]", curr->scoped, &curr->addr, curr->domain.c, curr->interface, curr->serviceID);
continue;
}
@@ -11350,6 +11370,9 @@ mDNSlocal void InitDNSConfig(mDNS *const m, DNSQuestion *const question)
question->triedAllServersOnce = 0;
question->noServerResponse = 0;
question->StopTime = 0;
+#if TARGET_OS_EMBEDDED
+ mDNSPlatformMemZero(&question->metrics, sizeof(question->metrics));
+#endif
// Need not initialize the DNS Configuration for Local Only OR P2P Questions
if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P)
@@ -11397,6 +11420,7 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
{
mDNSBool purge;
int i;
+ mDNSBool isCellBlocked = mDNSfalse;
// Note: In the case where we already have the answer to this question in our cache, that may be all the client
// wanted, and they may immediately cancel their question. In this case, sending an actual query on the wire would
@@ -11445,13 +11469,13 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
question->FlappingInterface1 = mDNSNULL;
question->FlappingInterface2 = mDNSNULL;
- // if kDNSServiceFlagsServiceIndex flag is SET by the client, then do NOT call mDNSPlatformGetServiceID()
+ // if kDNSServiceFlagsServiceIndex flag is SET by the client, then do NOT call mDNSPlatformGetDNSRoutePolicy()
// since we would already have the question->ServiceID in that case.
if (!(question->flags & kDNSServiceFlagsServiceIndex))
- question->ServiceID = mDNSPlatformGetServiceID(m, question);
+ mDNSPlatformGetDNSRoutePolicy(m, question, &isCellBlocked);
else
- LogInfo("InitCommonState: Query for %##s (%s), PID[%d], ServiceID %d is already set by client", question->qname.c,
- DNSTypeName(question->qtype), question->pid, question->ServiceID);
+ LogInfo("InitCommonState: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] is already set by client", question->qname.c,
+ DNSTypeName(question->qtype), question->pid, question->euid, question->ServiceID);
InitDNSConfig(m, question);
@@ -11462,10 +11486,10 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
// If ServiceID is 0 or the policy disallows making DNS requests,
// set DisallowPID
- question->DisallowPID = (question->ServiceID == 0 || (mDNSPlatformAllowPID(m, question) == 0));
+ question->DisallowPID = (question->ServiceID == 0 || (isCellBlocked && question->qDNSServer && question->qDNSServer->cellIntf));
if (question->DisallowPID)
LogInfo("InitCommonState: Query suppressed for %##s (%s), PID %d/ServiceID %d not allowed", question->qname.c,
- DNSTypeName(question->qtype), question->pid, question->ServiceID);
+ DNSTypeName(question->qtype), question->pid, question->ServiceID);
question->NextInDQList = mDNSNULL;
question->SendQNow = mDNSNULL;
@@ -11584,7 +11608,7 @@ mDNSlocal void InitDNSSECProxyState(mDNS *const m, DNSQuestion *const question)
{
if (question->qDNSServer->cellIntf)
{
- LogInfo("InitDNSSECProxyState: Turning off validation for %##s (%s); going over cell", question->qname.c, DNSTypeName(question->qtype));
+ debugf("InitDNSSECProxyState: Turning off validation for %##s (%s); going over cell", question->qname.c, DNSTypeName(question->qtype));
question->ValidationRequired = mDNSfalse;
}
if (DNSSECOptionalQuestion(question) && !(question->qDNSServer->req_DO))
@@ -11719,6 +11743,13 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
}
else
{
+#if TARGET_OS_WATCH
+ m->NumAllInterfaceQuestions++;
+ LogInfo("mDNS_StartQuery_internal: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %##s (%s)",
+ m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, question->qname.c, DNSTypeName(question->qtype));
+ if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
+ m->NetworkChanged = m->timenow;
+#endif
if (purge)
{
LogInfo("mDNS_StartQuery_internal: Purging for %##s", question->qname.c);
@@ -11763,14 +11794,35 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
#if !ForceAlerts
if (question->ThisQInterval >= 0) // Only log error message if the query was supposed to be active
#endif
- LogMsg("mDNS_StopQuery_internal: Question %##s (%s) not found in active list",
- question->qname.c, DNSTypeName(question->qtype));
-#if ForceAlerts
- *(long*)0 = 0;
-#endif
+ LogFatalError("mDNS_StopQuery_internal: Question %##s (%s) not found in active list", question->qname.c, DNSTypeName(question->qtype));
return(mStatus_BadReferenceErr);
}
+#if TARGET_OS_WATCH
+ if (question->InterfaceID != mDNSInterface_LocalOnly && question->InterfaceID != mDNSInterface_P2P && mDNSOpaque16IsZero(question->TargetQID))
+ {
+ if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
+ m->NetworkChanged = m->timenow;
+ m->NumAllInterfaceQuestions--;
+ LogInfo("mDNS_StopQuery_internal: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %##s (%s)",
+ m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, question->qname.c, DNSTypeName(question->qtype));
+ }
+#endif
+
+#if TARGET_OS_EMBEDDED
+ if (Question_uDNS(question) && !question->metrics.answered)
+ {
+ uDNSMetrics * metrics;
+ const domainname * queryName;
+ mDNSBool isForCellular;
+
+ metrics = &question->metrics;
+ queryName = metrics->originalQName ? metrics->originalQName : &question->qname;
+ isForCellular = (question->qDNSServer && question->qDNSServer->cellIntf);
+
+ MetricsUpdateUDNSStats(queryName, mDNSfalse, metrics->querySendCount, 0, isForCellular);
+ }
+#endif
// Take care to cut question from list *before* calling UpdateQuestionDuplicates
UpdateQuestionDuplicates(m, question);
// But don't trash ThisQInterval until afterwards.
@@ -11893,6 +11945,13 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
FreeAnonInfo(question->AnonInfo);
question->AnonInfo = mDNSNULL;
}
+#if TARGET_OS_EMBEDDED
+ if (question->metrics.originalQName)
+ {
+ mDNSPlatformMemFree(question->metrics.originalQName);
+ question->metrics.originalQName = mDNSNULL;
+ }
+#endif
return(mStatus_NoError);
}
@@ -12345,6 +12404,7 @@ mDNSexport mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, m
question->qnameOrig = mDNSNULL;
question->AnonInfo = mDNSNULL;
question->pid = mDNSPlatformGetPID();
+ question->euid = 0;
question->QuestionCallback = Callback;
question->QuestionContext = Context;
if (DomainType > mDNS_DomainTypeMax) return(mStatus_BadParamErr);
@@ -12461,26 +12521,20 @@ mDNSlocal void AdvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
{
char buffer[MAX_REVERSE_MAPPING_NAME];
NetworkInterfaceInfo *primary;
+ mDNSu8 recordType;
- if (!set->McastTxRx)
- {
- LogInfo("AdvertiseInterface: Returning, not multicast capable %s", set->ifname);
- return;
- }
-#if TARGET_OS_EMBEDDED
- if (!m->AutoTargetServices)
+ if (m->AutoTargetServices == 0)
{
LogInfo("AdvertiseInterface: Returning due to AutoTargetServices zero for %s", set->ifname);
return;
}
-#endif
primary = FindFirstAdvertisedInterface(m);
if (!primary) primary = set; // If no existing advertised interface, this new NetworkInterfaceInfo becomes our new primary
// If interface is marked as a direct link, we can assume the address record is unique
// and does not need to go through the probe phase of the probe/announce packet sequence.
- mDNSu8 recordType = (set->DirectLink ? kDNSRecordTypeKnownUnique : kDNSRecordTypeUnique);
+ recordType = (set->DirectLink ? kDNSRecordTypeKnownUnique : kDNSRecordTypeUnique);
if (set->DirectLink)
LogInfo("AdvertiseInterface: Marking address record as kDNSRecordTypeKnownUnique for %s", set->ifname);
@@ -12555,22 +12609,19 @@ mDNSlocal void AdvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
mDNSlocal void DeadvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
{
- NetworkInterfaceInfo *intf;
-
- // If we still have address records referring to this one, update them
- NetworkInterfaceInfo *primary = FindFirstAdvertisedInterface(m);
- AuthRecord *A = primary ? &primary->RR_A : mDNSNULL;
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->RR_A.RRSet == &set->RR_A)
- intf->RR_A.RRSet = A;
+ if (m->AutoTargetServices == 0)
+ {
+ LogInfo("DeadvertiseInterface: Returning due to AutoTargetServices zero for %s", set->ifname);
+ return;
+ }
// Unregister these records.
// When doing the mDNS_Exit processing, we first call DeadvertiseInterface for each interface, so by the time the platform
// support layer gets to call mDNS_DeregisterInterface, the address and PTR records have already been deregistered for it.
// Also, in the event of a name conflict, one or more of our records will have been forcibly deregistered.
// To avoid unnecessary and misleading warning messages, we check the RecordType before calling mDNS_Deregister_internal().
- if (set->RR_A.resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_A, mDNS_Dereg_normal);
- if (set->RR_PTR.resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_PTR, mDNS_Dereg_normal);
+ if (set->RR_A .resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_A, mDNS_Dereg_normal);
+ if (set->RR_PTR .resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_PTR, mDNS_Dereg_normal);
if (set->RR_HINFO.resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_HINFO, mDNS_Dereg_normal);
#if APPLE_OSX_mDNSResponder
@@ -12594,7 +12645,6 @@ mDNSlocal void AdvertiseAllInterfaceRecords(mDNS *const m)
mDNSlocal void DeadvertiseAllInterfaceRecords(mDNS *const m)
{
-#if TARGET_OS_EMBEDDED
NetworkInterfaceInfo *intf;
for (intf = m->HostInterfaces; intf; intf = intf->next)
{
@@ -12604,15 +12654,11 @@ mDNSlocal void DeadvertiseAllInterfaceRecords(mDNS *const m)
DeadvertiseInterface(m, intf);
}
}
-#else
- (void) m; //unused
-#endif
}
mDNSexport void mDNS_SetFQDN(mDNS *const m)
{
domainname newmname;
- NetworkInterfaceInfo *intf;
AuthRecord *rr;
newmname.c[0] = 0;
@@ -12625,14 +12671,8 @@ mDNSexport void mDNS_SetFQDN(mDNS *const m)
else
{
AssignDomainName(&m->MulticastHostname, &newmname);
-
- // 1. Stop advertising our address records on all interfaces
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->Advertise) DeadvertiseInterface(m, intf);
-
- // 2. Start advertising our address records using the new name
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->Advertise) AdvertiseInterface(m, intf);
+ DeadvertiseAllInterfaceRecords(m);
+ AdvertiseAllInterfaceRecords(m);
}
// 3. Make sure that any AutoTarget SRV records (and the like) get updated
@@ -12951,6 +12991,9 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
{
NetworkInterfaceInfo **p = &m->HostInterfaces;
mDNSBool revalidate = mDNSfalse;
+ NetworkInterfaceInfo *primary;
+ NetworkInterfaceInfo *intf;
+ AuthRecord *A;
mDNS_Lock(m);
@@ -12967,14 +13010,13 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
if (!set->InterfaceActive)
{
// If this interface not the active member of its set, update the v4/v6Available flags for the active member
- NetworkInterfaceInfo *intf;
for (intf = m->HostInterfaces; intf; intf = intf->next)
if (intf->InterfaceActive && intf->InterfaceID == set->InterfaceID)
UpdateInterfaceProtocols(m, intf);
}
else
{
- NetworkInterfaceInfo *intf = FirstInterfaceForID(m, set->InterfaceID);
+ intf = FirstInterfaceForID(m, set->InterfaceID);
if (intf)
{
LogInfo("mDNS_DeregisterInterface: Another representative of InterfaceID %d %s (%#a) exists;"
@@ -13007,7 +13049,7 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
if (set->McastTxRx && flapping)
{
- LogMsg("DeregisterInterface: Frequent transitions for interface %s (%#a)", set->ifname, &set->ip);
+ LogMsg("mDNS_DeregisterInterface: Frequent transitions for interface %s (%#a)", set->ifname, &set->ip);
m->mDNSStats.InterfaceDownFlap++;
}
@@ -13048,6 +13090,15 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
}
}
+ // If we still have address records referring to this one, update them.
+ // This is safe, because this NetworkInterfaceInfo has already been unlinked from the list,
+ // so the call to FindFirstAdvertisedInterface() won’t accidentally find it.
+ primary = FindFirstAdvertisedInterface(m);
+ A = primary ? &primary->RR_A : mDNSNULL;
+ for (intf = m->HostInterfaces; intf; intf = intf->next)
+ if (intf->RR_A.RRSet == &set->RR_A)
+ intf->RR_A.RRSet = A;
+
// If we were advertising on this interface, deregister those address and reverse-lookup records now
if (set->Advertise) DeadvertiseInterface(m, set);
@@ -13370,8 +13421,6 @@ mDNSexport mStatus mDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr,
e = &sr->Extras;
while (*e) e = &(*e)->next;
- if (ttl == 0) ttl = kStandardTTL;
-
extra->r.DependentOn = &sr->RR_SRV;
debugf("mDNS_AddRecordToService adding record to %##s %s %d",
@@ -14025,11 +14074,13 @@ mDNSexport void mDNSCoreReceiveRawPacket(mDNS *const m, const mDNSu8 *const p, c
else if (end >= p+34 && mDNSSameOpaque16(eth->ethertype, Ethertype_IPv4) && (pkt->v4.flagsfrags.b[0] & 0x1F) == 0 && pkt->v4.flagsfrags.b[1] == 0)
{
const mDNSu8 *const trans = p + 14 + (pkt->v4.vlen & 0xF) * 4;
+ const mDNSu8 * transEnd = p + 14 + mDNSVal16(pkt->v4.totlen);
+ if (transEnd > end) transEnd = end;
debugf("Got IPv4 %02X from %.4a to %.4a", pkt->v4.protocol, &pkt->v4.src, &pkt->v4.dst);
src.type = mDNSAddrType_IPv4; src.ip.v4 = pkt->v4.src;
dst.type = mDNSAddrType_IPv4; dst.ip.v4 = pkt->v4.dst;
- if (end >= trans + RequiredCapLen(pkt->v4.protocol))
- mDNSCoreReceiveRawTransportPacket(m, &eth->src, &src, &dst, pkt->v4.protocol, p, (TransportLayerPacket*)trans, end, InterfaceID, 0);
+ if (transEnd >= trans + RequiredCapLen(pkt->v4.protocol))
+ mDNSCoreReceiveRawTransportPacket(m, &eth->src, &src, &dst, pkt->v4.protocol, p, (TransportLayerPacket*)trans, transEnd, InterfaceID, 0);
}
// Is IPv6? Length must be at least 14 + 28 = 42 bytes
else if (end >= p+54 && mDNSSameOpaque16(eth->ethertype, Ethertype_IPv6))
@@ -14160,6 +14211,7 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
if (!rrcachestorage) rrcachesize = 0;
m->p = p;
+ m->NetworkChanged = 0;
m->CanReceiveUnicastOn5353 = mDNSfalse; // Assume we can't receive unicasts on 5353, unless platform layer tells us otherwise
m->AdvertiseLocalAddresses = AdvertiseLocalAddresses;
m->DivertMulticastAdvertisements = mDNSfalse;
@@ -14282,13 +14334,20 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
m->WABBrowseQueriesCount = 0;
m->WABLBrowseQueriesCount = 0;
m->WABRegQueriesCount = 0;
-#if !TARGET_OS_EMBEDDED
- m->mDNSOppCaching = mDNStrue;
+#if TARGET_OS_EMBEDDED || TARGET_OS_WATCH
+ m->AutoTargetServices = 0;
#else
- m->mDNSOppCaching = mDNSfalse;
+ m->AutoTargetServices = 1;
+#endif
+#if TARGET_OS_WATCH
+ m->NumAllInterfaceRecords = 0;
+ m->NumAllInterfaceQuestions = 0;
+#else
+ // Initialize to 1 for these targets to prevent not joining multicast group for interfaces when
+ // both of these values are zero.
+ m->NumAllInterfaceRecords = 1;
+ m->NumAllInterfaceQuestions = 1;
#endif
- m->AutoTargetServices = 0;
-
// NAT traversal fields
m->LLQNAT.clientCallback = mDNSNULL;
m->LLQNAT.clientContext = mDNSNULL;
@@ -14525,6 +14584,10 @@ mDNSlocal void SetConfigState(mDNS *const m, mDNSBool delete)
ptr->penaltyTime = 0;
NumUnicastDNSServers--;
ptr->flags |= DNSServer_FlagDelete;
+#if APPLE_OSX_mDNSResponder
+ if (ptr->flags & DNSServer_FlagUnreachable)
+ NumUnreachableDNSServers--;
+#endif
}
// We handle the mcast resolvers here itself as mDNSPlatformSetDNSConfig looks at
// mcast resolvers. Today we get both mcast and ucast configuration using the same
@@ -14539,6 +14602,10 @@ mDNSlocal void SetConfigState(mDNS *const m, mDNSBool delete)
ptr->penaltyTime = 0;
NumUnicastDNSServers++;
ptr->flags &= ~DNSServer_FlagDelete;
+#if APPLE_OSX_mDNSResponder
+ if (ptr->flags & DNSServer_FlagUnreachable)
+ NumUnreachableDNSServers++;
+#endif
}
for (mr = m->McastResolvers; mr; mr = mr->next)
mr->flags &= ~McastResolver_FlagDelete;
@@ -14587,7 +14654,7 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
// affecting them as they never change.
while (*mres)
{
- if (((*mres)->flags & DNSServer_FlagDelete) != 0)
+ if (((*mres)->flags & McastResolver_FlagDelete) != 0)
{
mr = *mres;
*mres = (*mres)->next;
@@ -14913,7 +14980,6 @@ mDNSlocal void DeregLoop(mDNS *const m, AuthRecord *const start)
mDNSexport void mDNS_StartExit(mDNS *const m)
{
- NetworkInterfaceInfo *intf;
AuthRecord *rr;
mDNS_Lock(m);
@@ -14953,9 +15019,7 @@ mDNSexport void mDNS_StartExit(mDNS *const m)
}
#endif
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->Advertise)
- DeadvertiseInterface(m, intf);
+ DeadvertiseAllInterfaceRecords(m);
// Shut down all our active NAT Traversals
while (m->NATTraversals)
@@ -15015,14 +15079,13 @@ mDNSexport void mDNS_StartExit(mDNS *const m)
mDNSexport void mDNS_FinalExit(mDNS *const m)
{
mDNSu32 rrcache_active = 0;
- mDNSu32 rrcache_totalused = 0;
+ mDNSu32 rrcache_totalused = m->rrcache_totalused;
mDNSu32 slot;
AuthRecord *rr;
LogInfo("mDNS_FinalExit: mDNSPlatformClose");
mDNSPlatformClose(m);
- rrcache_totalused = m->rrcache_totalused;
for (slot = 0; slot < CACHE_HASH_SLOTS; slot++)
{
while (m->rrcache_hash[slot])
@@ -15041,7 +15104,7 @@ mDNSexport void mDNS_FinalExit(mDNS *const m)
}
debugf("mDNS_FinalExit: RR Cache was using %ld records, %lu active", rrcache_totalused, rrcache_active);
if (rrcache_active != m->rrcache_active)
- LogMsg("*** ERROR *** rrcache_active %lu != m->rrcache_active %lu", rrcache_active, m->rrcache_active);
+ LogMsg("*** ERROR *** rrcache_totalused %lu; rrcache_active %lu != m->rrcache_active %lu", rrcache_totalused, rrcache_active, m->rrcache_active);
for (rr = m->ResourceRecords; rr; rr = rr->next)
LogMsg("mDNS_FinalExit failed to send goodbye for: %p %02X %s", rr, rr->resrec.RecordType, ARDisplayString(m, rr));
diff --git a/mDNSResponder/mDNSCore/mDNSDebug.h b/mDNSResponder/mDNSCore/mDNSDebug.h
index 5467ae64..68a696ef 100755
--- a/mDNSResponder/mDNSCore/mDNSDebug.h
+++ b/mDNSResponder/mDNSCore/mDNSDebug.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -148,12 +148,18 @@ extern void LogMsgWithLevel(mDNSLogLevel_t logLevel, const char *format, ...) IS
// (or completely overhauled to use the new "log to a separate file" facility)
#define LogMsgNoIdent LogMsg
+#if APPLE_OSX_mDNSResponder
+extern void LogFatalError(const char *format, ...);
+#else
+#define LogFatalError LogMsg
+#endif
+
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
extern void *mallocL(char *msg, unsigned int size);
extern void freeL(char *msg, void *x);
-extern void LogMemCorruption(const char *format, ...);
extern void uds_validatelists(void);
extern void udns_validatelists(void *const v);
+extern void LogMemCorruption(const char *format, ...);
#else
#define mallocL(X,Y) malloc(Y)
#define freeL(X,Y) free(Y)
diff --git a/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h b/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
index bafeb026..48f8280d 100755
--- a/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
+++ b/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -70,6 +70,7 @@
#include "mDNSDebug.h"
#if APPLE_OSX_mDNSResponder
#include <uuid/uuid.h>
+#include <TargetConditionals.h>
#endif
#ifdef __cplusplus
@@ -90,20 +91,14 @@ extern "C" {
// In order to disable the above features pass the option to your compiler, e.g. -D UNICAST_DISABLED
-// Additionally, the LIMITED_RESOURCES_TARGET compile option will eliminate caching and
-// and reduce the maximum DNS message sizes.
+// Additionally, the LIMITED_RESOURCES_TARGET compile option will reduce the maximum DNS message sizes.
#ifdef LIMITED_RESOURCES_TARGET
// Don't support jumbo frames
-#define AbsoluteMaxDNSMessageData 1500
-// By the time you add IPv6 header (40 bytes) UDP header (8 bytes) and DNS message header (12 bytes)
-// this makes 1560 which is 60 bytes over the standard Ethernet MTU. D'oh!
-
+// 40 (IPv6 header) + 8 (UDP header) + 12 (DNS message header) + 1440 (DNS message body) = 1500 total
+#define AbsoluteMaxDNSMessageData 1440
// StandardAuthRDSize is 264 (256+8), which is large enough to hold a maximum-sized SRV record (6 + 256 bytes)
#define MaximumRDSize 264
-// Don't cache anything
-#define AUTH_HASH_SLOTS 1
-#define CACHE_HASH_SLOTS 1
#endif
// ***************************************************************************
@@ -556,7 +551,7 @@ typedef packedstruct
{
mDNSu8 vlen;
mDNSu8 tos;
- mDNSu16 totlen;
+ mDNSOpaque16 totlen;
mDNSOpaque16 id;
mDNSOpaque16 flagsfrags;
mDNSu8 ttl;
@@ -1320,8 +1315,11 @@ enum
enum
{
- DNSServer_FlagDelete = 1,
- DNSServer_FlagNew = 2
+ DNSServer_FlagDelete = 0x1,
+ DNSServer_FlagNew = 0x2,
+#if APPLE_OSX_mDNSResponder
+ DNSServer_FlagUnreachable = 0x4,
+#endif
};
enum
@@ -1413,7 +1411,7 @@ struct ResourceRecord_struct
// that are interface-specific (e.g. address records, especially linklocal addresses)
const domainname *name;
RData *rdata; // Pointer to storage for this rdata
- DNSServer *rDNSServer; // Unicast DNS server authoritative for this entry;null for multicast
+ DNSServer *rDNSServer; // Unicast DNS server authoritative for this entry; null for multicast
AnonymousInfo *AnonInfo; // Anonymous Information
};
@@ -1502,7 +1500,7 @@ struct AuthRecord_struct
AuthRecord *next; // Next in list; first element of structure for efficiency reasons
// Field Group 1: Common ResourceRecord fields
- ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit
+ ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64)
// Field Group 2: Persistent metadata for Authoritative Records
AuthRecord *Additional1; // Recommended additional record to include in response (e.g. SRV for PTR record)
@@ -1634,7 +1632,7 @@ typedef struct ARListElem
struct CacheRecord_struct
{
CacheRecord *next; // Next in list; first element of structure for efficiency reasons
- ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit
+ ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64)
// Transient state for Cache Records
CacheRecord *NextInKAList; // Link to the next element in the chain of known answers to send
@@ -1658,13 +1656,12 @@ struct CacheRecord_struct
CacheRecord *soa; // SOA record to return for proxy questions
mDNSAddr sourceAddress; // node from which we received this record
- // Size to here is 76 bytes when compiling 32-bit; 104 bytes when compiling 64-bit
+ // Size to here is 76 bytes when compiling 32-bit; 104 bytes when compiling 64-bit (now 160 bytes for 64-bit)
RData_small smallrdatastorage; // Storage for small records is right here (4 bytes header + 68 bytes data = 72 bytes)
};
// Should match the CacheGroup_struct members, except namestorage[]. Only used to calculate
-// the size of the namestorage array in CacheGroup_struct so that
-// sizeof(CacheGroup) == sizeof(CacheRecord)
+// the size of the namestorage array in CacheGroup_struct so that sizeof(CacheGroup) == sizeof(CacheRecord)
struct CacheGroup_base
{
CacheGroup *next;
@@ -1887,6 +1884,17 @@ typedef enum { DNSSECValNotRequired = 0, DNSSECValRequired, DNSSECValInProgress,
// RFC 4122 defines it to be 16 bytes
#define UUID_SIZE 16
+#if TARGET_OS_EMBEDDED
+typedef struct
+{
+ domainname * originalQName; // Name of original A/AAAA record if this question is for a CNAME record.
+ mDNSu32 querySendCount; // Number of queries that have been sent to DNS servers so far.
+ mDNSs32 firstQueryTime; // The time when the first query was sent to a DNS server.
+ mDNSBool answered; // Has this question been answered?
+
+} uDNSMetrics;
+#endif
+
struct DNSQuestion_struct
{
// Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
@@ -1997,9 +2005,13 @@ struct DNSQuestion_struct
mDNSu8 ProxyDNSSECOK; // Proxy Question with EDNS0 DNSSEC OK bit set
mDNSs32 pid; // Process ID of the client that is requesting the question
mDNSu8 uuid[UUID_SIZE]; // Unique ID of the client that is requesting the question (valid only if pid is zero)
+ mDNSu32 euid; // Effective User Id of the client that is requesting the question
domainname *qnameOrig; // Copy of the original question name if it is not fully qualified
mDNSQuestionCallback *QuestionCallback;
void *QuestionContext;
+#if TARGET_OS_EMBEDDED
+ uDNSMetrics metrics; // Data used for collecting unicast DNS query metrics.
+#endif
};
typedef struct
@@ -2145,6 +2157,8 @@ struct NetworkInterfaceInfo_struct
mDNSu8 SendGoodbyes; // Send goodbyes on this interface while sleeping
mDNSBool DirectLink; // a direct link, indicating we can skip the probe for
// address records
+ mDNSBool SupportsUnicastMDNSResponse; // Indicates that the interface supports unicast responses
+ // to Bonjour queries. Generally true for an interface.
};
#define SLE_DELETE 0x00000001
@@ -2259,6 +2273,7 @@ typedef struct
mDNSu32 CacheRefreshed; // Number of times the cache was refreshed due to a response
mDNSu32 WakeOnResolves; // Number of times we did a wake on resolve
} mDNSStatistics;
+
extern void LogMDNSStatistics(mDNS *const m);
struct mDNS_struct
@@ -2269,6 +2284,7 @@ struct mDNS_struct
// all required data is passed as parameters to that function.
mDNS_PlatformSupport *p; // Pointer to platform-specific data of indeterminite size
+ mDNSs32 NetworkChanged;
mDNSBool CanReceiveUnicastOn5353;
mDNSBool AdvertiseLocalAddresses;
mDNSBool DivertMulticastAdvertisements; // from interfaces that do not advertise local addresses to local-only
@@ -2368,7 +2384,7 @@ struct mDNS_struct
mDNSs32 ProbeFailTime;
mDNSu32 NumFailedProbes;
mDNSs32 SuppressProbes;
- Platform_t mDNS_plat;
+ Platform_t mDNS_plat; // Why is this here in the “only required for mDNS Responder” section? -- SC
// Unicast-specific data
mDNSs32 NextuDNSEvent; // uDNS next event
@@ -2454,9 +2470,10 @@ struct mDNS_struct
TrustAnchor *TrustAnchors;
int notifyToken;
- int uds_listener_skt; // Listening socket for incoming UDS clients
- mDNSBool mDNSOppCaching; // Opportunistic Caching
+ int uds_listener_skt; // Listening socket for incoming UDS clients. This should not be here -- it's private to uds_daemon.c and nothing to do with mDNSCore -- SC
mDNSu32 AutoTargetServices; // # of services that have AutoTarget set
+ mDNSu32 NumAllInterfaceRecords; // Right now we count *all* multicast records here. Later we may want to change to count interface-specific records separately. (This count includes records on the DuplicateRecords list too.)
+ mDNSu32 NumAllInterfaceQuestions; // Right now we count *all* multicast questions here. Later we may want to change to count interface-specific questions separately.
DNSSECStatistics DNSSECStats;
mDNSStatistics mDNSStats;
@@ -2468,8 +2485,8 @@ struct mDNS_struct
};
#define FORALL_CACHERECORDS(SLOT,CG,CR) \
- for ((SLOT) = 0; (SLOT) < CACHE_HASH_SLOTS; (SLOT)++) \
- for ((CG)=m->rrcache_hash[(SLOT)]; (CG); (CG)=(CG)->next) \
+ for ((SLOT) = 0; (SLOT) < CACHE_HASH_SLOTS; (SLOT)++) \
+ for ((CG)=m->rrcache_hash[(SLOT)]; (CG); (CG)=(CG)->next) \
for ((CR) = (CG)->members; (CR); (CR)=(CR)->next)
// ***************************************************************************
@@ -2530,6 +2547,9 @@ extern const mDNSOpaque64 zeroOpaque64;
extern mDNSBool StrictUnicastOrdering;
extern mDNSu8 NumUnicastDNSServers;
+#if APPLE_OSX_mDNSResponder
+extern mDNSu8 NumUnreachableDNSServers;
+#endif
#define localdomain (*(const domainname *)"\x5" "local")
#define DeviceInfoName (*(const domainname *)"\xC" "_device-info" "\x4" "_tcp")
@@ -2648,7 +2668,6 @@ extern mStatus mDNS_Init (mDNS *const m, mDNS_PlatformSupport *const p,
extern void mDNS_ConfigChanged(mDNS *const m);
extern void mDNS_GrowCache (mDNS *const m, CacheEntity *storage, mDNSu32 numrecords);
-extern void mDNS_GrowAuth (mDNS *const m, AuthEntity *storage, mDNSu32 numrecords);
extern void mDNS_StartExit (mDNS *const m);
extern void mDNS_FinalExit (mDNS *const m);
#define mDNS_Close(m) do { mDNS_StartExit(m); mDNS_FinalExit(m); } while(0)
@@ -2784,7 +2803,7 @@ extern mStatus mDNS_AdvertiseDomains(mDNS *const m, AuthRecord *rr, mDNS_DomainT
#define mDNS_StopAdvertiseDomains mDNS_Deregister
extern mDNSOpaque16 mDNS_NewMessageID(mDNS *const m);
-extern mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr, mDNSBool *myself);
+extern mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr);
extern DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question);
extern mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question);
@@ -3195,6 +3214,7 @@ extern mStatus mDNSPlatformGetPrimaryInterface(mDNS *const m, mDNSAddr *v4, m
extern void mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status);
extern void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, const char *reason);
+extern void mDNSPlatformPreventSleep(mDNS *const m, mDNSu32 timeout, const char *reason);
extern void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration);
extern mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID);
@@ -3317,11 +3337,13 @@ extern void RemoveAutoTunnel6Record(mDNS *const m);
extern mDNSBool RecordReadyForSleep(mDNS *const m, AuthRecord *rr);
// For now this LocalSleepProxy 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
-extern mStatus ActivateLocalProxy(mDNS *const m, NetworkInterfaceInfo *const intf);
+extern mStatus ActivateLocalProxy(mDNS *const m, NetworkInterfaceInfo *const intf, mDNSBool *keepaliveOnly);
extern void mDNSPlatformUpdateDNSStatus(mDNS *const m, DNSQuestion *q);
extern void mDNSPlatformTriggerDNSRetry(mDNS *const m, DNSQuestion *v4q, DNSQuestion *v6q);
extern void mDNSPlatformLogToFile(int log_level, const char *buffer);
extern mDNSBool SupportsInNICProxy(NetworkInterfaceInfo *const intf);
+extern mStatus SymptomReporterDNSServerReachable(mDNS *const m, const mDNSAddr *addr);
+extern mStatus SymptomReporterDNSServerUnreachable(DNSServer *s);
#endif
typedef void ProxyCallback (mDNS *const m, void *socket, void *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
@@ -3336,11 +3358,11 @@ extern mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DNSMes
extern void mDNSPlatformSleepAssertion(mDNS *const m, double timeout);
#endif
-extern mDNSBool mDNSPlatformAllowPID(mDNS *const m, DNSQuestion *q);
-extern mDNSs32 mDNSPlatformGetServiceID(mDNS *const m, DNSQuestion *q);
+extern void mDNSPlatformGetDNSRoutePolicy(mDNS *const m, DNSQuestion *q, mDNSBool *isBlocked);
extern void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q);
extern mDNSs32 mDNSPlatformGetPID(void);
-
+extern mDNSBool mDNSValidKeepAliveRecord(AuthRecord *rr);
+
// ***************************************************************************
#if 0
#pragma mark -
@@ -3556,21 +3578,18 @@ struct CompileTimeAssertionChecks_mDNS
char sizecheck_AuthRecord [(sizeof(AuthRecord) <= 1208) ? 1 : -1];
char sizecheck_CacheRecord [(sizeof(CacheRecord) <= 232) ? 1 : -1];
char sizecheck_CacheGroup [(sizeof(CacheGroup) <= 232) ? 1 : -1];
- char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 832) ? 1 : -1];
+ char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 864) ? 1 : -1];
-// Checks commented out when sizeof(DNSQuestion) change cascaded into having to change yet another
-// set of hardcoded size values because these structures contain one or more DNSQuestion
-// instances.
-// char sizecheck_ZoneData [(sizeof(ZoneData) <= 1648) ? 1 : -1];
+ char sizecheck_ZoneData [(sizeof(ZoneData) <= 1700) ? 1 : -1];
char sizecheck_NATTraversalInfo [(sizeof(NATTraversalInfo) <= 200) ? 1 : -1];
char sizecheck_HostnameInfo [(sizeof(HostnameInfo) <= 3050) ? 1 : -1];
char sizecheck_DNSServer [(sizeof(DNSServer) <= 340) ? 1 : -1];
-// char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 6988) ? 1 : -1];
+ char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 7184) ? 1 : -1];
char sizecheck_ServiceRecordSet [(sizeof(ServiceRecordSet) <= 5540) ? 1 : -1];
char sizecheck_DomainAuthInfo [(sizeof(DomainAuthInfo) <= 7888) ? 1 : -1];
-// char sizecheck_ServiceInfoQuery [(sizeof(ServiceInfoQuery) <= 3302) ? 1 : -1];
+ char sizecheck_ServiceInfoQuery [(sizeof(ServiceInfoQuery) <= 3488) ? 1 : -1];
#if APPLE_OSX_mDNSResponder
-// char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1160) ? 1 : -1];
+ char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1208) ? 1 : -1];
#endif
};
diff --git a/mDNSResponder/mDNSCore/nsec.c b/mDNSResponder/mDNSCore/nsec.c
index a9f16b3f..09d27356 100644
--- a/mDNSResponder/mDNSCore/nsec.c
+++ b/mDNSResponder/mDNSCore/nsec.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -611,7 +611,7 @@ mDNSlocal mDNSBool NSECNoDataError(mDNS *const m, ResourceRecord *rr, domainname
{
const domainname *oname = rr->name; // owner name
- if (wildcard) *wildcard = mDNSNULL;
+ *wildcard = mDNSNULL;
// RFC 4035
//
// section 3.1.3.1 : Name matches. Prove that the type does not exist and also CNAME is
@@ -676,10 +676,10 @@ mDNSlocal mDNSBool NSECNoDataError(mDNS *const m, ResourceRecord *rr, domainname
// a subdomain e.g., y.x.example or z.y.x.example and so on.
if (oname->c[0] == 1 && oname->c[1] == '*')
{
- int r, s;
+ int s;
const domainname *ce = SkipLeadingLabels(oname, 1);
- r = DNSSECCanonicalOrder(name, ce, &s);
+ DNSSECCanonicalOrder(name, ce, &s);
if (s)
{
if (RRAssertsExistence(rr, qtype) || RRAssertsExistence(rr, kDNSType_CNAME))
@@ -912,18 +912,18 @@ mDNSlocal void NoDataProof(mDNS *const m, DNSSECVerifier *dv, CacheRecord *ncr)
// First verify wildcard NSEC and then when we are done, we
// will verify the noname nsec
dv->pendingNSEC = r;
- LogDNSSEC("NoDataProof: Verifying wild and noname %s", RRDisplayString(m, nsec_wild));
+ LogDNSSEC("NoDataProof: Verifying wild and noname %s", nsec_wild ? RRDisplayString(m, nsec_wild) : "NULL");
VerifyNSEC(m, nsec_wild, mDNSNULL, dv, ncr, NoDataNSECCallback);
}
else if ((dv->flags & WILDCARD_PROVES_NONAME_EXISTS) ||
(dv->flags & NSEC_PROVES_NOTYPE_EXISTS))
{
- LogDNSSEC("NoDataProof: Verifying wild %s", RRDisplayString(m, nsec_wild));
+ LogDNSSEC("NoDataProof: Verifying wild %s", nsec_wild ? RRDisplayString(m, nsec_wild) : "NULL");
VerifyNSEC(m, nsec_wild, mDNSNULL, dv, ncr, mDNSNULL);
}
else if (dv->flags & NSEC_PROVES_NONAME_EXISTS)
{
- LogDNSSEC("NoDataProof: Verifying noname %s", RRDisplayString(m, nsec_noname));
+ LogDNSSEC("NoDataProof: Verifying noname %s", nsec_noname ? RRDisplayString(m, nsec_noname) : "NULL");
VerifyNSEC(m, nsec_noname, mDNSNULL, dv, ncr, mDNSNULL);
}
return;
diff --git a/mDNSResponder/mDNSCore/nsec.h b/mDNSResponder/mDNSCore/nsec.h
index 3dbb841f..198f57db 100644
--- a/mDNSResponder/mDNSCore/nsec.h
+++ b/mDNSResponder/mDNSCore/nsec.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#ifndef __NSEC_H
#define __NSEC_H
diff --git a/mDNSResponder/mDNSCore/nsec3.c b/mDNSResponder/mDNSCore/nsec3.c
index a039418a..c16a42d5 100644
--- a/mDNSResponder/mDNSCore/nsec3.c
+++ b/mDNSResponder/mDNSCore/nsec3.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -332,7 +332,7 @@ mDNSlocal mDNSBool NSEC3Find(mDNS *const m, NSEC3FindValues val, CacheRecord *nc
}
}
- if ((val == NSEC3Covers || val == NSEC3CEProof) && !(*closerEncloser))
+ if ((val == NSEC3Covers || val == NSEC3CEProof) && (!closerEncloser || !(*closerEncloser)))
{
if (NSEC3CoversName(m, cr, hashName, hlen, b32Name, b32len))
{
@@ -349,23 +349,22 @@ mDNSlocal mDNSBool NSEC3Find(mDNS *const m, NSEC3FindValues val, CacheRecord *nc
// 2.3) If there is a matching NSEC3 RR in the response and the flag
// was set, then the proof is complete, and SNAME is the closest
// encloser.
- if (val == NSEC3CEProof)
+ if (val == NSEC3CEProof && closestEncloser && *closestEncloser)
{
- if (*closestEncloser && *closerEncloser)
+ if (closerEncloser && *closerEncloser)
{
LogDNSSEC("NSEC3Find: Found closest and closer encloser");
return mDNStrue;
}
-
- // 2.4) If there is a matching NSEC3 RR in the response, but the flag
- // is not set, then the response is bogus.
- //
- // Note: We don't have to wait till we finish trying all the names. If the matchName
- // happens, we found the closest encloser which means we should have found the closer
- // encloser before.
-
- if (*closestEncloser && !(*closerEncloser))
+ else
{
+ // 2.4) If there is a matching NSEC3 RR in the response, but the flag
+ // is not set, then the response is bogus.
+ //
+ // Note: We don't have to wait till we finish trying all the names. If the matchName
+ // happens, we found the closest encloser which means we should have found the closer
+ // encloser before.
+
LogDNSSEC("NSEC3Find: Found closest, but not closer encloser");
return mDNSfalse;
}
@@ -388,8 +387,7 @@ mDNSlocal mDNSBool NSEC3ClosestEncloserProof(mDNS *const m, CacheRecord *ncr, do
// Note: It is possible that closestEncloser and closerEncloser are the same.
if (!closestEncloser || !closerEncloser || !ce)
{
- LogMsg("NSEC3ClosestEncloserProof: ClosestEncloser %p or CloserEncloser %p ce %p, something is NULL", *closestEncloser,
- *closerEncloser, *ce);
+ LogMsg("NSEC3ClosestEncloserProof: ClosestEncloser %p or CloserEncloser %p ce %p, something is NULL", closestEncloser, closerEncloser, ce);
return mDNSfalse;
}
diff --git a/mDNSResponder/mDNSCore/nsec3.h b/mDNSResponder/mDNSCore/nsec3.h
index ce3b85a3..be32b809 100644
--- a/mDNSResponder/mDNSCore/nsec3.h
+++ b/mDNSResponder/mDNSCore/nsec3.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/mDNSResponder/mDNSCore/uDNS.c b/mDNSResponder/mDNSCore/uDNS.c
index ce12d01a..3ba88b5c 100755
--- a/mDNSResponder/mDNSCore/uDNS.c
+++ b/mDNSResponder/mDNSCore/uDNS.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,6 +51,9 @@ mDNSBool StrictUnicastOrdering = mDNSfalse;
// arbitrary limitation of 64 DNSServers can be removed.
mDNSu8 NumUnicastDNSServers = 0;
#define MAX_UNICAST_DNS_SERVERS 64
+#if APPLE_OSX_mDNSResponder
+mDNSu8 NumUnreachableDNSServers = 0;
+#endif
#define SetNextuDNSEvent(m, rr) { \
if ((m)->NextuDNSEvent - ((rr)->LastAPTime + (rr)->ThisAPInterval) >= 0) \
@@ -164,6 +167,12 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
if (tmp)
{
+#if APPLE_OSX_mDNSResponder
+ if (tmp->flags & DNSServer_FlagDelete)
+ {
+ tmp->flags &= ~DNSServer_FlagUnreachable;
+ }
+#endif
tmp->flags &= ~DNSServer_FlagDelete;
*p = tmp; // move to end of list, to ensure ordering from platform layer
}
@@ -214,7 +223,8 @@ mDNSexport void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 re
{
DNSServer *new;
DNSServer *orig = q->qDNSServer;
-
+ mDNSu8 rcode = '\0';
+
mDNS_CheckLock(m);
LogInfo("PenalizeDNSServer: Penalizing DNS server %#a question for question %p %##s (%s) SuppressUnusable %d",
@@ -224,10 +234,13 @@ mDNSexport void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 re
// return the error, then return the first error.
if (mDNSOpaque16IsZero(q->responseFlags))
q->responseFlags = responseFlags;
+
+ rcode = (mDNSu8)(responseFlags.b[1] & kDNSFlag1_RC_Mask);
// After we reset the qDNSServer to NULL, we could get more SERV_FAILS that might end up
// peanlizing again.
- if (!q->qDNSServer) goto end;
+ if (!q->qDNSServer)
+ goto end;
// If strict ordering of unicast servers needs to be preserved, we just lookup
// the next best match server below
@@ -246,6 +259,10 @@ mDNSexport void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 re
{
LogInfo("PenalizeDNSServer: Not Penalizing PTR question");
}
+ else if ((rcode == kDNSFlag1_RC_FormErr) || (rcode == kDNSFlag1_RC_ServFail) || (rcode == kDNSFlag1_RC_NotImpl) || (rcode == kDNSFlag1_RC_Refused))
+ {
+ LogInfo("PenalizeDNSServer: Not Penalizing DNS Server since it at least responded with rcode %d", rcode);
+ }
else
{
LogInfo("PenalizeDNSServer: Penalizing question type %d", q->qtype);
@@ -812,11 +829,8 @@ mDNSexport mStatus mDNS_StartNATOperation_internal(mDNS *const m, NATTraversalIn
{
if (traversal == *n)
{
- LogMsg("Error! Tried to add a NAT traversal that's already in the active list: request %p Prot %d Int %d TTL %d",
+ LogFatalError("Error! Tried to add a NAT traversal that's already in the active list: request %p Prot %d Int %d TTL %d",
traversal, traversal->Protocol, mDNSVal16(traversal->IntPort), traversal->NATLease);
- #if ForceAlerts
- *(long*)0 = 0;
- #endif
return(mStatus_AlreadyRegistered);
}
if (traversal->Protocol && traversal->Protocol == (*n)->Protocol && mDNSSameIPPort(traversal->IntPort, (*n)->IntPort) &&
@@ -1894,6 +1908,7 @@ mDNSlocal mStatus GetZoneData_StartQuery(mDNS *const m, ZoneData *zd, mDNSu16 qt
zd->question.qnameOrig = mDNSNULL;
zd->question.AnonInfo = mDNSNULL;
zd->question.pid = mDNSPlatformGetPID();
+ zd->question.euid = 0;
zd->question.QuestionCallback = GetZoneData_QuestionCallback;
zd->question.QuestionContext = zd;
@@ -2583,6 +2598,7 @@ mDNSlocal void GetStaticHostname(mDNS *m)
q->qnameOrig = mDNSNULL;
q->AnonInfo = mDNSNULL;
q->pid = mDNSPlatformGetPID();
+ q->euid = 0;
q->QuestionCallback = FoundStaticHostname;
q->QuestionContext = mDNSNULL;
@@ -3991,6 +4007,10 @@ mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNS
msg->h.numAnswers, msg->h.numAnswers == 1 ? ", " : "s,",
msg->h.numAuthorities, msg->h.numAuthorities == 1 ? "y, " : "ies,",
msg->h.numAdditionals, msg->h.numAdditionals == 1 ? "" : "s", end - msg->data);
+#if APPLE_OSX_mDNSResponder
+ if (NumUnreachableDNSServers > 0)
+ SymptomReporterDNSServerReachable(m, srcaddr);
+#endif
if (QR_OP == StdR)
{
@@ -4141,7 +4161,7 @@ mDNSexport void LLQGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneI
q->servAddr = zeroAddr;
q->servPort = zeroIPPort;
- if (!err && zoneInfo && !mDNSIPPortIsZero(zoneInfo->Port) && !mDNSAddressIsZero(&zoneInfo->Addr) && zoneInfo->Host.c[0])
+ if (!err && !mDNSIPPortIsZero(zoneInfo->Port) && !mDNSAddressIsZero(&zoneInfo->Addr) && zoneInfo->Host.c[0])
{
q->servAddr = zoneInfo->Addr;
q->servPort = zoneInfo->Port;
@@ -4238,10 +4258,14 @@ mDNSlocal void PrivateQueryGotZoneData(mDNS *const m, mStatus err, const ZoneDat
// Called in normal callback context (i.e. mDNS_busy and mDNS_reentrancy are both 1)
mDNSexport void RecordRegistrationGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneData)
{
- AuthRecord *newRR = (AuthRecord*)zoneData->ZoneDataContext;
+ AuthRecord *newRR;
AuthRecord *ptr;
int c1, c2;
+ if (!zoneData) { LogMsg("ERROR: RecordRegistrationGotZoneData invoked with NULL result and no error"); return; }
+
+ newRR = (AuthRecord*)zoneData->ZoneDataContext;
+
if (newRR->nta != zoneData)
LogMsg("RecordRegistrationGotZoneData: nta (%p) != zoneData (%p) %##s (%s)", newRR->nta, zoneData, newRR->resrec.name->c, DNSTypeName(newRR->resrec.rrtype));
@@ -4267,8 +4291,6 @@ mDNSexport void RecordRegistrationGotZoneData(mDNS *const m, mStatus err, const
return;
}
- if (!zoneData) { LogMsg("ERROR: RecordRegistrationGotZoneData invoked with NULL result and no error"); return; }
-
if (newRR->resrec.rrclass != zoneData->ZoneClass)
{
LogMsg("ERROR: New resource record's class (%d) does not match zone class (%d)", newRR->resrec.rrclass, zoneData->ZoneClass);
@@ -4656,7 +4678,7 @@ mDNSlocal void handle_unanswered_query(mDNS *const m)
// Note: req_DO affects only DNSSEC_VALIDATION_SECURE_OPTIONAL questions;
// DNSSEC_VALIDATION_SECURE questions ignores req_DO.
- if (q->qDNSServer && !q->qDNSServer->DNSSECAware && q->qDNSServer->req_DO)
+ if (!q->qDNSServer->DNSSECAware && q->qDNSServer->req_DO)
{
q->qDNSServer->retransDO++;
if (q->qDNSServer->retransDO == MAX_DNSSEC_RETRANSMISSIONS)
@@ -4714,6 +4736,9 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
LogInfo("uDNS_CheckCurrentQuestion: Sent %d unanswered queries for %##s (%s) to %#a:%d (%##s)",
q->unansweredQueries, q->qname.c, DNSTypeName(q->qtype), &orig->addr, mDNSVal16(orig->port), orig->domain.c);
+#if APPLE_OSX_mDNSResponder
+ SymptomReporterDNSServerUnreachable(orig);
+#endif
PenalizeDNSServer(m, q, zeroID);
q->noServerResponse = 1;
}
@@ -4798,7 +4823,19 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
mDNSPlatformSetuDNSSocktOpt(q->LocalSocket, &q->qDNSServer->addr, q);
}
if (!q->LocalSocket) err = mStatus_NoMemoryErr; // If failed to make socket (should be very rare), we'll try again next time
- else err = mDNSSendDNSMessage(m, &m->omsg, end, q->qDNSServer->interface, q->LocalSocket, &q->qDNSServer->addr, q->qDNSServer->port, mDNSNULL, mDNSNULL, q->UseBackgroundTrafficClass);
+ else
+ {
+ err = mDNSSendDNSMessage(m, &m->omsg, end, q->qDNSServer->interface, q->LocalSocket, &q->qDNSServer->addr, q->qDNSServer->port, mDNSNULL, mDNSNULL, q->UseBackgroundTrafficClass);
+#if TARGET_OS_EMBEDDED
+ if (!err)
+ {
+ if (q->metrics.querySendCount++ == 0)
+ {
+ q->metrics.firstQueryTime = m->timenow;
+ }
+ }
+#endif
+ }
}
}
@@ -4916,7 +4953,6 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
mDNSexport void CheckNATMappings(mDNS *m)
{
- mStatus err = mStatus_NoError;
mDNSBool rfc1918 = mDNSv4AddrIsRFC1918(&m->AdvertisedV4.ip.v4);
mDNSBool HaveRoutable = !rfc1918 && !mDNSIPv4AddressIsZero(m->AdvertisedV4.ip.v4);
m->NextScheduledNATOp = m->timenow + 0x3FFFFFFF;
@@ -4974,7 +5010,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
cur->retryInterval = NATMAP_INIT_RETRY;
}
- err = uDNS_SendNATMsg(m, cur, mDNStrue); // Will also do UPnP discovery for us, if necessary
+ uDNS_SendNATMsg(m, cur, mDNStrue); // Will also do UPnP discovery for us, if necessary
if (cur->ExpiryTime) // If have active mapping then set next renewal time halfway to expiry
NATSetNextRenewalTime(m, cur);