summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSCore
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-19 08:56:09 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-20 11:23:33 +0200
commit4c086a244624bf36865edcfa4309c333d7d7200d (patch)
treee566ffc50a6b6fdb46702ac57c8e7c4088b60b42 /mDNSResponder/mDNSCore
parentmDNSResponder: Update to v765.50.9 (diff)
downloadrtems-libbsd-4c086a244624bf36865edcfa4309c333d7d7200d.tar.bz2
mDNSResponder: Update to v878.1.1
The sources can be obtained via: https://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-878.1.1.tar.gz Update #3522.
Diffstat (limited to 'mDNSResponder/mDNSCore')
-rw-r--r--mDNSResponder/mDNSCore/DNSCommon.c75
-rw-r--r--mDNSResponder/mDNSCore/DNSCommon.h5
-rw-r--r--mDNSResponder/mDNSCore/anonymous.c12
-rw-r--r--mDNSResponder/mDNSCore/dnsproxy.c89
-rw-r--r--mDNSResponder/mDNSCore/dnsproxy.h8
-rw-r--r--mDNSResponder/mDNSCore/dnssec.c37
-rwxr-xr-xmDNSResponder/mDNSCore/mDNS.c801
-rwxr-xr-xmDNSResponder/mDNSCore/mDNSEmbeddedAPI.h179
-rw-r--r--mDNSResponder/mDNSCore/nsec.c9
-rw-r--r--mDNSResponder/mDNSCore/nsec3.c5
-rwxr-xr-xmDNSResponder/mDNSCore/uDNS.c146
-rwxr-xr-xmDNSResponder/mDNSCore/uDNS.h2
12 files changed, 704 insertions, 664 deletions
diff --git a/mDNSResponder/mDNSCore/DNSCommon.c b/mDNSResponder/mDNSCore/DNSCommon.c
index 3ea9a307..be8e1065 100644
--- a/mDNSResponder/mDNSCore/DNSCommon.c
+++ b/mDNSResponder/mDNSCore/DNSCommon.c
@@ -21,6 +21,10 @@
#include "CryptoAlg.h"
#include "anonymous.h"
+#ifdef UNIT_TEST
+#include "unittest.h"
+#endif
+
// Disable certain benign warnings with Microsoft compilers
#if (defined(_MSC_VER))
// Disable "conditional expression is constant" warning for debug macros.
@@ -111,7 +115,8 @@ mDNSexport const mDNSOpaque16 UpdateRespFlags = { { kDNSFlag0_QR_Response | kDNS
mDNSexport const mDNSOpaque16 SubscribeFlags = { { kDNSFlag0_QR_Query | kDNSFlag0_OP_Subscribe, 0 } };
mDNSexport const mDNSOpaque16 UnSubscribeFlags= { { kDNSFlag0_QR_Query | kDNSFlag0_OP_UnSubscribe, 0 } };
-mDNSexport const mDNSOpaque64 zeroOpaque64 = { { 0 } };
+mDNSexport const mDNSOpaque64 zeroOpaque64 = { { 0 } };
+mDNSexport const mDNSOpaque128 zeroOpaque128 = { { 0 } };
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
@@ -622,6 +627,8 @@ mDNSexport mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip)
#pragma mark - Domain Name Utility Functions
#endif
+#if !APPLE_OSX_mDNSResponder
+
mDNSexport mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b)
{
int i;
@@ -642,6 +649,8 @@ mDNSexport mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b)
return(mDNStrue);
}
+#endif // !APPLE_OSX_mDNSResponder
+
mDNSexport mDNSBool SameDomainName(const domainname *const d1, const domainname *const d2)
{
const mDNSu8 * a = d1->c;
@@ -971,10 +980,6 @@ mDNSexport void ConvertUTF8PstringToRFC1034HostLabel(const mDNSu8 UTF8Name[], do
hostlabel->c[0] = (mDNSu8)(ptr - &hostlabel->c[1]);
}
-#define ValidTransportProtocol(X) ( (X)[0] == 4 && (X)[1] == '_' && \
- ((((X)[2] | 0x20) == 'u' && ((X)[3] | 0x20) == 'd') || (((X)[2] | 0x20) == 't' && ((X)[3] | 0x20) == 'c')) && \
- ((X)[4] | 0x20) == 'p')
-
mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
const domainlabel *name, const domainname *type, const domainname *const domain)
{
@@ -1033,10 +1038,6 @@ mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
{
LogMsg("Bad service type in %#s.%##s%##s Application protocol name must be underscore plus 1-15 characters. "
"See <http://www.dns-sd.org/ServiceTypes.html>", name->c, type->c, domain->c);
-#if APPLE_OSX_mDNSResponder
- ConvertDomainNameToCString(type, typeBuf);
- mDNSASLLog(mDNSNULL, "serviceType.nameTooLong", "noop", typeBuf, "");
-#endif
}
if (len < 2 || len >= 0x40 || (len > 16 && !SameDomainName(domain, &localdomain))) return(mDNSNULL);
if (src[1] != '_') { errormsg = "Application protocol name must begin with underscore"; goto fail; }
@@ -1053,19 +1054,13 @@ mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
if (src[i] == '_' && loggedUnderscore == mDNSfalse)
{
ConvertDomainNameToCString(type, typeBuf);
- mDNSASLLog(mDNSNULL, "serviceType.nameWithUnderscore", "noop", typeBuf, "");
+ LogInfo("ConstructServiceName: Service type with non-leading underscore %s", typeBuf);
loggedUnderscore = mDNStrue;
}
#endif
continue;
}
errormsg = "Application protocol name must contain only letters, digits, and hyphens";
-#if APPLE_OSX_mDNSResponder
- {
- ConvertDomainNameToCString(type, typeBuf);
- mDNSASLLog(mDNSNULL, "serviceType.nameWithIllegalCharacters", "noop", typeBuf, "");
- }
-#endif
goto fail;
}
for (i=0; i<=len; i++) *dst++ = *src++;
@@ -2754,12 +2749,12 @@ mDNSexport const mDNSu8 *getDomainName(const DNSMessage *const msg, const mDNSu8
while (1) // Read sequence of labels
{
+ int i;
+ mDNSu16 offset;
const mDNSu8 len = *ptr++; // Read length of this label
if (len == 0) break; // If length is zero, that means this name is complete
switch (len & 0xC0)
{
- int i;
- mDNSu16 offset;
case 0x00: if (ptr + len >= end) // Remember: expect at least one more byte for the root label
{ debugf("getDomainName: Malformed domain name (overruns packet end)"); return(mDNSNULL); }
@@ -3457,12 +3452,6 @@ mDNSexport const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage
rr->CRActiveQuestion = mDNSNULL;
rr->UnansweredQueries = 0;
rr->LastUnansweredTime= 0;
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- rr->MPUnansweredQ = 0;
- rr->MPLastUnansweredQT= 0;
- rr->MPUnansweredKA = 0;
- rr->MPExpectingKA = mDNSfalse;
-#endif
rr->NextInCFList = mDNSNULL;
rr->resrec.InterfaceID = InterfaceID;
@@ -3617,16 +3606,27 @@ mDNSexport const rdataOPT *GetLLQOptData(mDNS *const m, const DNSMessage *const
}
// Get the lease life of records in a dynamic update
-// returns 0 on error or if no lease present
-mDNSexport mDNSu32 GetPktLease(mDNS *m, DNSMessage *msg, const mDNSu8 *end)
+mDNSexport mDNSBool GetPktLease(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, mDNSu32 *const lease)
{
- mDNSu32 result = 0;
const mDNSu8 *ptr = LocateOptRR(msg, end, DNSOpt_LeaseData_Space);
- if (ptr) ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
- if (ptr && m->rec.r.resrec.rdlength >= DNSOpt_LeaseData_Space && m->rec.r.resrec.rdata->u.opt[0].opt == kDNSOpt_Lease)
- result = m->rec.r.resrec.rdata->u.opt[0].u.updatelease;
- m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
- return(result);
+ if (ptr)
+ {
+ ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
+ if (ptr && m->rec.r.resrec.RecordType != kDNSRecordTypePacketNegative && m->rec.r.resrec.rrtype == kDNSType_OPT)
+ {
+ const rdataOPT *o;
+ const rdataOPT *const e = (const rdataOPT *)&m->rec.r.resrec.rdata->u.data[m->rec.r.resrec.rdlength];
+ for (o = &m->rec.r.resrec.rdata->u.opt[0]; o < e; o++)
+ if (o->opt == kDNSOpt_Lease)
+ {
+ *lease = o->u.updatelease;
+ m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
+ return mDNStrue;
+ }
+ }
+ m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
+ }
+ return mDNSfalse;
}
mDNSlocal const mDNSu8 *DumpRecords(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end, int count, char *label)
@@ -3725,6 +3725,10 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
#pragma mark - Packet Sending Functions
#endif
+#ifdef UNIT_TEST
+// Run the unit test of mDNSSendDNSMessage
+UNITTEST_SENDDNSMESSAGE
+#else
// Stub definition of TCPSocket_struct so we can access flags field. (Rest of TCPSocket_struct is platform-dependent.)
struct TCPSocket_struct { TCPSocketFlags flags; /* ... */ };
// Stub definition of UDPSocket_struct so we can access port field. (Rest of UDPSocket_struct is platform-dependent.)
@@ -3826,6 +3830,7 @@ mDNSexport mStatus mDNSSendDNSMessage(mDNS *const m, DNSMessage *const msg, mDNS
return(status);
}
+#endif // UNIT_TEST
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
@@ -3883,7 +3888,7 @@ mDNSlocal AuthRecord *AnyLocalRecordReady(const mDNS *const m)
mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m)
{
- mDNSs32 e = m->timenow + 0x78000000;
+ mDNSs32 e = m->timenow + FutureTime;
if (m->mDNSPlatformStatus != mStatus_NoError) return(e);
if (m->NewQuestions)
{
@@ -4057,7 +4062,8 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
for (c = *fmt; c != 0; c = *++fmt)
{
- if (c != '%')
+ unsigned long n;
+ if (c != '%')
{
*sbuffer++ = (char)c;
if (++nwritten >= buflen) goto exit;
@@ -4113,7 +4119,6 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
conv:
switch (c) // perform appropriate conversion
{
- unsigned long n;
case 'h': F.hSize = 1; c = *++fmt; goto conv;
case 'l': // fall through
case 'L': F.lSize = 1; c = *++fmt; goto conv;
diff --git a/mDNSResponder/mDNSCore/DNSCommon.h b/mDNSResponder/mDNSCore/DNSCommon.h
index 2da19700..e1ef261e 100644
--- a/mDNSResponder/mDNSCore/DNSCommon.h
+++ b/mDNSResponder/mDNSCore/DNSCommon.h
@@ -240,8 +240,7 @@ extern const mDNSu8 *NSEC3HashName(const domainname *name, rdataNSEC3 *nsec3, co
#pragma mark - DNS Message Parsing Functions
#endif
-#define AuthHashSlot(X) (DomainNameHashValue(X) % AUTH_HASH_SLOTS)
-#define HashSlot(X) (DomainNameHashValue(X) % CACHE_HASH_SLOTS)
+#define HashSlotFromNameHash(X) ((X) % CACHE_HASH_SLOTS)
extern mDNSu32 DomainNameHashValue(const domainname *const name);
extern void SetNewRData(ResourceRecord *const rr, RData *NewRData, mDNSu16 rdlength);
extern const mDNSu8 *skipDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end);
@@ -260,7 +259,7 @@ extern const mDNSu8 *LocateAuthorities(const DNSMessage *const msg, const mDNSu8
extern const mDNSu8 *LocateAdditionals(const DNSMessage *const msg, const mDNSu8 *const end);
extern const mDNSu8 *LocateOptRR(const DNSMessage *const msg, const mDNSu8 *const end, int minsize);
extern const rdataOPT *GetLLQOptData(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end);
-extern mDNSu32 GetPktLease(mDNS *m, DNSMessage *msg, const mDNSu8 *end);
+extern mDNSBool GetPktLease(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, mDNSu32 *const lease);
extern void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *transport,
const mDNSAddr *srcaddr, mDNSIPPort srcport,
const mDNSAddr *dstaddr, mDNSIPPort dstport, const DNSMessage *const msg, const mDNSu8 *const end);
diff --git a/mDNSResponder/mDNSCore/anonymous.c b/mDNSResponder/mDNSCore/anonymous.c
index aaaebc27..fde3ed80 100644
--- a/mDNSResponder/mDNSCore/anonymous.c
+++ b/mDNSResponder/mDNSCore/anonymous.c
@@ -240,6 +240,12 @@ mDNSexport void SetAnonData(DNSQuestion *q, ResourceRecord *rr, mDNSBool ForQues
debugf("SetAnonData: question %##s(%p), rr %##s(%p)", q->qname.c, q->AnonInfo, rr->name->c, rr->AnonInfo);
if (ForQuestion)
{
+ if (q->AnonInfo->AnonDataLen < rr->AnonInfo->AnonDataLen)
+ {
+ mDNSPlatformMemFree(q->AnonInfo->AnonData);
+ q->AnonInfo->AnonData = mDNSNULL;
+ }
+
if (!q->AnonInfo->AnonData)
{
q->AnonInfo->AnonData = mDNSPlatformMemAllocate(rr->AnonInfo->AnonDataLen);
@@ -251,6 +257,12 @@ mDNSexport void SetAnonData(DNSQuestion *q, ResourceRecord *rr, mDNSBool ForQues
}
else
{
+ if (rr->AnonInfo->AnonDataLen < q->AnonInfo->AnonDataLen)
+ {
+ mDNSPlatformMemFree(rr->AnonInfo->AnonData);
+ rr->AnonInfo->AnonData = mDNSNULL;
+ }
+
if (!rr->AnonInfo->AnonData)
{
rr->AnonInfo->AnonData = mDNSPlatformMemAllocate(q->AnonInfo->AnonDataLen);
diff --git a/mDNSResponder/mDNSCore/dnsproxy.c b/mDNSResponder/mDNSCore/dnsproxy.c
index 2afb59d1..a94c005e 100644
--- a/mDNSResponder/mDNSCore/dnsproxy.c
+++ b/mDNSResponder/mDNSCore/dnsproxy.c
@@ -19,6 +19,8 @@
#ifndef UNICAST_DISABLED
+mDNSexport mDNS mDNSStorage;
+
// Implementation Notes
//
// DNS Proxy listens on port 53 (UDPv4v6 & TCPv4v6) for DNS queries. It handles only
@@ -72,7 +74,7 @@ struct DNSProxyClient_struct {
};
#define MIN_DNS_MESSAGE_SIZE 512
-DNSProxyClient *DNSProxyClients;
+static DNSProxyClient *DNSProxyClients;
mDNSlocal void FreeDNSProxyClient(DNSProxyClient *pc)
{
@@ -130,7 +132,7 @@ mDNSexport mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DN
return ptr;
}
-mDNSlocal mDNSu8 *AddEDNS0Option(mDNS *const m, mDNSu8 *ptr, mDNSu8 *limit)
+mDNSlocal mDNSu8 *AddEDNS0Option(mDNSu8 *ptr, mDNSu8 *limit)
{
int len = 4096;
@@ -139,7 +141,7 @@ mDNSlocal mDNSu8 *AddEDNS0Option(mDNS *const m, mDNSu8 *ptr, mDNSu8 *limit)
LogInfo("AddEDNS0Option: not enough space");
return mDNSNULL;
}
- m->omsg.h.numAdditionals++;
+ mDNSStorage.omsg.h.numAdditionals++;
ptr[0] = 0;
ptr[1] = (mDNSu8) (kDNSType_OPT >> 8);
ptr[2] = (mDNSu8) (kDNSType_OPT & 0xFF);
@@ -180,9 +182,9 @@ mDNSlocal mDNSOpaque16 SetResponseFlags(DNSProxyClient *pc, const mDNSOpaque16 r
return rFlags;
}
-mDNSlocal mDNSu8 *AddResourceRecords(mDNS *const m, DNSProxyClient *pc, mDNSu8 **prevptr, mStatus *error)
+mDNSlocal mDNSu8 *AddResourceRecords(DNSProxyClient *pc, mDNSu8 **prevptr, mStatus *error)
{
- mDNSu32 slot;
+ mDNS *const m = &mDNSStorage;
CacheGroup *cg;
CacheRecord *cr;
int len = sizeof(DNSMessageHeader);
@@ -229,9 +231,8 @@ mDNSlocal mDNSu8 *AddResourceRecords(mDNS *const m, DNSProxyClient *pc, mDNSu8 *
again:
nsec = soa = cname = mDNSNULL;
- slot = HashSlot(&tempQName);
- cg = CacheGroupForName(m, slot, tempQNameHash, &tempQName);
+ cg = CacheGroupForName(m, tempQNameHash, &tempQName);
if (!cg)
{
LogInfo("AddResourceRecords: CacheGroup not found for %##s", tempQName.c);
@@ -355,7 +356,7 @@ again:
}
if (pc->rcvBufSize)
{
- ptr = AddEDNS0Option(m, ptr, limit);
+ ptr = AddEDNS0Option(ptr, limit);
if (!ptr)
{
*prevptr = orig;
@@ -408,7 +409,7 @@ mDNSlocal void ProxyClientCallback(mDNS *const m, DNSQuestion *question, const R
return;
}
}
- ptr = AddResourceRecords(m, pc, &prevptr, &error);
+ ptr = AddResourceRecords(pc, &prevptr, &error);
if (!ptr)
{
LogInfo("ProxyClientCallback: AddResourceRecords NULL for %##s (%s)", &pc->qname.c, DNSTypeName(pc->q.qtype));
@@ -494,9 +495,10 @@ done:
FreeDNSProxyClient(pc);
}
-mDNSlocal void SendError(mDNS *const m, void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *dstaddr,
+mDNSlocal void SendError(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *dstaddr,
const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, mDNSBool tcp, void *context, mDNSu8 rcode)
{
+ mDNS *const m = &mDNSStorage;
int pktlen = (int)(end - (mDNSu8 *)msg);
// RFC 1035 requires that we copy the question back and RFC 2136 is okay with sending nothing
@@ -509,7 +511,8 @@ mDNSlocal void SendError(mDNS *const m, void *socket, DNSMessage *const msg, con
mDNSPlatformMemCopy(&m->omsg.h, &msg->h, sizeof(DNSMessageHeader));
m->omsg.h.flags.b[0] |= kDNSFlag0_QR_Response;
m->omsg.h.flags.b[1] = rcode;
- mDNSPlatformMemCopy(m->omsg.data, (mDNSu8 *)&msg->h.numQuestions, pktlen);
+ mDNSPlatformMemCopy(m->omsg.data, (mDNSu8 *)&msg->data, (pktlen - sizeof(DNSMessageHeader)));
+
if (!tcp)
{
mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, InterfaceID, socket, dstaddr, dstport, mDNSNULL, mDNSNULL,
@@ -523,14 +526,12 @@ mDNSlocal void SendError(mDNS *const m, void *socket, DNSMessage *const msg, con
mDNSPlatformDisposeProxyContext(context);
}
-mDNSlocal DNSQuestion *IsDuplicateClient(const mDNS *const m, const mDNSAddr *const addr, const mDNSIPPort port, const mDNSOpaque16 id,
+mDNSlocal DNSQuestion *IsDuplicateClient(const mDNSAddr *const addr, const mDNSIPPort port, const mDNSOpaque16 id,
const DNSQuestion *const question)
{
DNSProxyClient *pc;
- (void) m; // unused
-
- for (pc = DNSProxyClients; pc; pc = pc->next)
+ for (pc = DNSProxyClients; pc; pc = pc->next)
{
if (mDNSSameAddress(&pc->addr, addr) &&
mDNSSameIPPort(pc->port, port) &&
@@ -546,8 +547,9 @@ mDNSlocal DNSQuestion *IsDuplicateClient(const mDNS *const m, const mDNSAddr *co
return(mDNSNULL);
}
-mDNSlocal mDNSBool CheckDNSProxyIpIntf(const mDNS *const m, mDNSInterfaceID InterfaceID)
+mDNSlocal mDNSBool CheckDNSProxyIpIntf(mDNSInterfaceID InterfaceID)
{
+ mDNS *const m = &mDNSStorage;
int i;
mDNSu32 ip_ifindex = (mDNSu32)(unsigned long)InterfaceID;
@@ -570,9 +572,10 @@ mDNSlocal mDNSBool CheckDNSProxyIpIntf(const mDNS *const m, mDNSInterfaceID Inte
}
-mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
+mDNSlocal void ProxyCallbackCommon(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, mDNSBool tcp, void *context)
{
+ mDNS *const m = &mDNSStorage;
mDNSu8 QR_OP;
const mDNSu8 *ptr;
DNSQuestion q, *qptr;
@@ -586,7 +589,7 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, DNSMessage *cons
debugf("ProxyCallbackCommon: DNS Query coming from InterfaceID %p", InterfaceID);
// Ignore if the DNS Query is not from a Valid Input InterfaceID
- if (!CheckDNSProxyIpIntf(m, InterfaceID))
+ if (!CheckDNSProxyIpIntf(InterfaceID))
{
LogMsg("ProxyCallbackCommon: Rejecting DNS Query coming from InterfaceID %p", InterfaceID);
return;
@@ -598,14 +601,6 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, DNSMessage *cons
return;
}
- QR_OP = (mDNSu8)(msg->h.flags.b[0] & kDNSFlag0_QROP_Mask);
- if (QR_OP != kDNSFlag0_QR_Query)
- {
- LogInfo("ProxyCallbackCommon: Not a query(%d) for pkt from %#a:%d", QR_OP, srcaddr, mDNSVal16(srcport));
- SendError(m, socket, msg, end, srcaddr, srcport, InterfaceID, tcp, context, kDNSFlag1_RC_NotImpl);
- return;
- }
-
// Read the integer parts which are in IETF byte-order (MSB first, LSB second)
ptr = (mDNSu8 *)&msg->h.numQuestions;
msg->h.numQuestions = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]);
@@ -613,11 +608,19 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, DNSMessage *cons
msg->h.numAuthorities = (mDNSu16)((mDNSu16)ptr[4] << 8 | ptr[5]);
msg->h.numAdditionals = (mDNSu16)((mDNSu16)ptr[6] << 8 | ptr[7]);
+ QR_OP = (mDNSu8)(msg->h.flags.b[0] & kDNSFlag0_QROP_Mask);
+ if (QR_OP != kDNSFlag0_QR_Query)
+ {
+ LogInfo("ProxyCallbackCommon: Not a query(%d) for pkt from %#a:%d", QR_OP, srcaddr, mDNSVal16(srcport));
+ SendError(socket, msg, end, srcaddr, srcport, InterfaceID, tcp, context, kDNSFlag1_RC_NotImpl);
+ return;
+ }
+
if (msg->h.numQuestions != 1 || msg->h.numAnswers || msg->h.numAuthorities)
{
LogInfo("ProxyCallbackCommon: Malformed pkt from %#a:%d, Q:%d, An:%d, Au:%d", srcaddr, mDNSVal16(srcport),
msg->h.numQuestions, msg->h.numAnswers, msg->h.numAuthorities);
- SendError(m, socket, msg, end, srcaddr, srcport, InterfaceID, tcp, context, kDNSFlag1_RC_FormErr);
+ SendError(socket, msg, end, srcaddr, srcport, InterfaceID, tcp, context, kDNSFlag1_RC_FormErr);
return;
}
ptr = msg->data;
@@ -625,7 +628,7 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, DNSMessage *cons
if (!ptr)
{
LogInfo("ProxyCallbackCommon: Question cannot be parsed for pkt from %#a:%d", srcaddr, mDNSVal16(srcport));
- SendError(m, socket, msg, end, srcaddr, srcport, InterfaceID, tcp, context, kDNSFlag1_RC_FormErr);
+ SendError(socket, msg, end, srcaddr, srcport, InterfaceID, tcp, context, kDNSFlag1_RC_FormErr);
return;
}
else
@@ -653,7 +656,7 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, DNSMessage *cons
LogInfo("ProxyCallbackCommon: EDNS0 opt not present in Question %##s (%s), ptr %p", q.qname.c, DNSTypeName(q.qtype), ptr);
}
- qptr = IsDuplicateClient(m, srcaddr, srcport, msg->h.id, &q);
+ qptr = IsDuplicateClient(srcaddr, srcport, msg->h.id, &q);
if (qptr)
{
LogInfo("ProxyCallbackCommon: Found a duplicate for pkt from %#a:%d, ignoring this", srcaddr, mDNSVal16(srcport));
@@ -730,21 +733,21 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, DNSMessage *cons
mDNS_StartQuery(m, &pc->q);
}
-mDNSexport void ProxyUDPCallback(mDNS *const m, void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
+mDNSexport void ProxyUDPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context)
{
LogInfo("ProxyUDPCallback: DNS Message from %#a:%d to %#a:%d length %d", srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), (int)(end - (mDNSu8 *)msg));
- ProxyCallbackCommon(m, socket, msg, end, srcaddr, srcport, dstaddr, dstport, InterfaceID, mDNSfalse, context);
+ ProxyCallbackCommon(socket, msg, end, srcaddr, srcport, dstaddr, dstport, InterfaceID, mDNSfalse, context);
}
-mDNSexport void ProxyTCPCallback(mDNS *const m, void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
+mDNSexport void ProxyTCPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context)
{
LogInfo("ProxyTCPCallback: DNS Message from %#a:%d to %#a:%d length %d", srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), (int)(end - (mDNSu8 *)msg));
// If the connection was closed from the other side or incoming packet does not match stored input interface list, locate the client
// state and free it.
- if (((end - (mDNSu8 *)msg) == 0) || (!CheckDNSProxyIpIntf(m, InterfaceID)))
+ if (((end - (mDNSu8 *)msg) == 0) || (!CheckDNSProxyIpIntf(InterfaceID)))
{
DNSProxyClient **ppc = &DNSProxyClients;
DNSProxyClient **prevpc;
@@ -767,11 +770,12 @@ mDNSexport void ProxyTCPCallback(mDNS *const m, void *socket, DNSMessage *const
FreeDNSProxyClient(*ppc);
return;
}
- ProxyCallbackCommon(m, socket, msg, end, srcaddr, srcport, dstaddr, dstport, InterfaceID, mDNStrue, context);
+ ProxyCallbackCommon(socket, msg, end, srcaddr, srcport, dstaddr, dstport, InterfaceID, mDNStrue, context);
}
-mDNSexport void DNSProxyInit(mDNS *const m, mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf)
+mDNSexport void DNSProxyInit(mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf)
{
+ mDNS *const m = &mDNSStorage;
int i;
// Store DNSProxy Interface fields in mDNS struct
@@ -783,8 +787,9 @@ mDNSexport void DNSProxyInit(mDNS *const m, mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf
m->dp_ipintf[1], m->dp_ipintf[2], m->dp_ipintf[3], m->dp_ipintf[4], m->dp_opintf);
}
-mDNSexport void DNSProxyTerminate(mDNS *const m)
+mDNSexport void DNSProxyTerminate(void)
{
+ mDNS *const m = &mDNSStorage;
int i;
// Clear DNSProxy Interface fields from mDNS struct
@@ -797,9 +802,8 @@ mDNSexport void DNSProxyTerminate(mDNS *const m)
}
#else // UNICAST_DISABLED
-mDNSexport void ProxyUDPCallback(mDNS *const m, void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context)
+mDNSexport void ProxyUDPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context)
{
- (void) m;
(void) socket;
(void) msg;
(void) end;
@@ -811,9 +815,8 @@ mDNSexport void ProxyUDPCallback(mDNS *const m, void *socket, DNSMessage *const
(void) context;
}
-mDNSexport void ProxyTCPCallback(mDNS *const m, void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context)
+mDNSexport void ProxyTCPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context)
{
- (void) m;
(void) socket;
(void) msg;
(void) end;
@@ -825,15 +828,13 @@ mDNSexport void ProxyTCPCallback(mDNS *const m, void *socket, DNSMessage *const
(void) context;
}
-mDNSexport void DNSProxyInit(mDNS *const m, mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf)
+mDNSexport void DNSProxyInit(mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf)
{
- (void) m;
(void) IpIfArr;
(void) OpIf;
}
-extern void DNSProxyTerminate(mDNS *const m)
+extern void DNSProxyTerminate(void)
{
- (void) m;
}
diff --git a/mDNSResponder/mDNSCore/dnsproxy.h b/mDNSResponder/mDNSCore/dnsproxy.h
index a2abdfbf..6889e73a 100644
--- a/mDNSResponder/mDNSCore/dnsproxy.h
+++ b/mDNSResponder/mDNSCore/dnsproxy.h
@@ -21,11 +21,11 @@
#include "mDNSEmbeddedAPI.h"
#include "DNSCommon.h"
-extern void ProxyUDPCallback(mDNS *const m, void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
+extern void ProxyUDPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context);
-extern void ProxyTCPCallback(mDNS *const m, void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
+extern void ProxyTCPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context);
-extern void DNSProxyInit(mDNS *const m, mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf);
-extern void DNSProxyTerminate(mDNS *const m);
+extern void DNSProxyInit(mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf);
+extern void DNSProxyTerminate(void);
#endif // __DNS_PROXY_H
diff --git a/mDNSResponder/mDNSCore/dnssec.c b/mDNSResponder/mDNSCore/dnssec.c
index 514a488c..9525655f 100644
--- a/mDNSResponder/mDNSCore/dnssec.c
+++ b/mDNSResponder/mDNSCore/dnssec.c
@@ -707,7 +707,6 @@ mDNSexport void ValidateRRSIG(DNSSECVerifier *dv, RRVerifierSet type, const Reso
mDNSlocal mStatus CheckRRSIGForRRSet(mDNS *const m, DNSSECVerifier *dv, CacheRecord **negcr)
{
- mDNSu32 slot;
CacheGroup *cg;
CacheRecord *cr;
RRVerifier *rv;
@@ -722,8 +721,7 @@ mDNSlocal mStatus CheckRRSIGForRRSet(mDNS *const m, DNSSECVerifier *dv, CacheRec
}
rv = dv->rrset;
- slot = HashSlot(&rv->name);
- cg = CacheGroupForName(m, slot, rv->namehash, &rv->name);
+ cg = CacheGroupForName(m, rv->namehash, &rv->name);
if (!cg)
{
debugdnssec("CheckRRSIGForRRSet: cg null");
@@ -807,7 +805,6 @@ mDNSlocal void CheckOneKeyForRRSIG(DNSSECVerifier *dv, const ResourceRecord *con
mDNSlocal mStatus CheckKeyForRRSIG(mDNS *const m, DNSSECVerifier *dv, CacheRecord **negcr)
{
- mDNSu32 slot;
mDNSu32 namehash;
CacheGroup *cg;
CacheRecord *cr;
@@ -825,9 +822,8 @@ mDNSlocal mStatus CheckKeyForRRSIG(mDNS *const m, DNSSECVerifier *dv, CacheRecor
rrsig = (rdataRRSig *)dv->rrsig->rdata;
name = (domainname *)&rrsig->signerName;
- slot = HashSlot(name);
namehash = DomainNameHashValue(name);
- cg = CacheGroupForName(m, slot, namehash, name);
+ cg = CacheGroupForName(m, namehash, name);
if (!cg)
{
debugdnssec("CheckKeyForRRSIG: cg null for %##s", name->c);
@@ -887,7 +883,6 @@ mDNSlocal void CheckOneRRSIGForKey(DNSSECVerifier *dv, const ResourceRecord *con
mDNSlocal mStatus CheckRRSIGForKey(mDNS *const m, DNSSECVerifier *dv, CacheRecord **negcr)
{
- mDNSu32 slot;
mDNSu32 namehash;
CacheGroup *cg;
CacheRecord *cr;
@@ -909,9 +904,8 @@ mDNSlocal mStatus CheckRRSIGForKey(mDNS *const m, DNSSECVerifier *dv, CacheRecor
rrsig = (rdataRRSig *)dv->rrsig->rdata;
name = (domainname *)&rrsig->signerName;
- slot = HashSlot(name);
namehash = DomainNameHashValue(name);
- cg = CacheGroupForName(m, slot, namehash, name);
+ cg = CacheGroupForName(m, namehash, name);
if (!cg)
{
debugdnssec("CheckRRSIGForKey: cg null %##s", name->c);
@@ -1010,7 +1004,6 @@ mDNSlocal void CheckOneDSForKey(DNSSECVerifier *dv, const ResourceRecord *const
mDNSlocal mStatus CheckDSForKey(mDNS *const m, DNSSECVerifier *dv, CacheRecord **negcr)
{
- mDNSu32 slot;
mDNSu32 namehash;
CacheGroup *cg;
CacheRecord *cr;
@@ -1030,9 +1023,8 @@ mDNSlocal mStatus CheckDSForKey(mDNS *const m, DNSSECVerifier *dv, CacheRecord *
}
rrsig = (rdataRRSig *)dv->rrsig->rdata;
name = (domainname *)&rrsig->signerName;
- slot = HashSlot(name);
namehash = DomainNameHashValue(name);
- cg = CacheGroupForName(m, slot, namehash, name);
+ cg = CacheGroupForName(m, namehash, name);
if (!cg)
{
debugdnssec("CheckDSForKey: cg null for %s", name->c);
@@ -2336,7 +2328,6 @@ mDNSlocal void SetTTLRRSet(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus statu
CacheRecord *rr;
RRVerifier *rrsigv;
rdataRRSig *rrsig;
- mDNSu32 slot;
CacheGroup *cg;
mDNSu32 rrTTL, rrsigTTL, rrsigOrigTTL, rrsigTimeTTL;
domainname *qname;
@@ -2368,8 +2359,7 @@ mDNSlocal void SetTTLRRSet(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus statu
question.ThisQInterval = -1;
InitializeQuestion(m, &question, dv->InterfaceID, qname, qtype, mDNSNULL, mDNSNULL);
- slot = HashSlot(&question.qname);
- cg = CacheGroupForName(m, slot, question.qnamehash, &question.qname);
+ cg = CacheGroupForName(m, question.qnamehash, &question.qname);
if (!cg)
{
@@ -2691,7 +2681,7 @@ mDNSlocal void DNSSECNoResponse(mDNS *const m, DNSSECVerifier *dv)
{
CacheGroup *cg;
CacheRecord *cr;
- mDNSu32 slot, namehash;
+ mDNSu32 namehash;
ResourceRecord *answer = mDNSNULL;
LogDNSSEC("DNSSECNoResponse: called");
@@ -2704,10 +2694,9 @@ mDNSlocal void DNSSECNoResponse(mDNS *const m, DNSSECVerifier *dv)
BumpDNSSECStats(m, kStatsActionSet, kStatsTypeStatus, DNSSEC_NoResponse);
- slot = HashSlot(&dv->origName);
namehash = DomainNameHashValue(&dv->origName);
- cg = CacheGroupForName(m, (const mDNSu32)slot, namehash, &dv->origName);
+ cg = CacheGroupForName(m, namehash, &dv->origName);
if (!cg)
{
LogDNSSEC("DNSSECNoResponse: cg NULL for %##s (%s)", dv->origName.c, DNSTypeName(dv->origType));
@@ -3033,7 +3022,7 @@ done:
mDNSlocal void DNSSECValidationCB(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus status)
{
- mDNSu32 slot, namehash;
+ mDNSu32 namehash;
CacheGroup *cg;
CacheRecord *cr;
@@ -3053,10 +3042,9 @@ mDNSlocal void DNSSECValidationCB(mDNS *const m, DNSSECVerifier *dv, DNSSECStatu
ProveInsecure(m, dv, mDNSNULL, mDNSNULL);
return;
}
- slot = HashSlot(&dv->origName);
namehash = DomainNameHashValue(&dv->origName);
- cg = CacheGroupForName(m, (const mDNSu32)slot, namehash, &dv->origName);
+ cg = CacheGroupForName(m, namehash, &dv->origName);
if (!cg)
{
LogDNSSEC("DNSSECValidationCB: cg NULL for %##s (%s)", dv->origName.c, DNSTypeName(dv->origType));
@@ -3082,8 +3070,7 @@ mDNSlocal void DNSSECValidationCB(mDNS *const m, DNSSECVerifier *dv, DNSSECStatu
mDNSexport void VerifySignature(mDNS *const m, DNSSECVerifier *dv, DNSQuestion *q)
{
- mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
CacheRecord *rr;
mDNSBool first = mDNSfalse;
static mDNSBool TrustAnchorsUpdated = mDNSfalse;
@@ -3319,14 +3306,12 @@ mDNSlocal mStatus TrustedKey(mDNS *const m, DNSSECVerifier *dv)
mDNSlocal CacheRecord* NegativeCacheRecordForRR(mDNS *const m, const ResourceRecord *const rr)
{
- mDNSu32 slot;
mDNSu32 namehash;
CacheGroup *cg;
CacheRecord *cr;
- slot = HashSlot(rr->name);
namehash = DomainNameHashValue(rr->name);
- cg = CacheGroupForName(m, slot, namehash, rr->name);
+ cg = CacheGroupForName(m, namehash, rr->name);
if (!cg)
{
LogMsg("NegativeCacheRecordForRR: cg null %##s", rr->name->c);
diff --git a/mDNSResponder/mDNSCore/mDNS.c b/mDNSResponder/mDNSCore/mDNS.c
index a58a6c1a..0d4d8ae4 100755
--- a/mDNSResponder/mDNSCore/mDNS.c
+++ b/mDNSResponder/mDNSCore/mDNS.c
@@ -45,6 +45,7 @@
#endif
#include "dns_sd.h" // for kDNSServiceFlags* definitions
+#include "dns_sd_internal.h"
#if APPLE_OSX_mDNSResponder
#include <WebFilterDNS/WebFilterDNS.h>
@@ -65,15 +66,22 @@ void WCFConnectionDealloc(WCFConnection* c) __attribute__((weak_import));
#define NO_WCF 1
#endif // APPLE_OSX_mDNSResponder
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
#include "Metrics.h"
#endif
+#if USE_DNS64
+#include "DNS64.h"
+#endif
+
+#ifdef UNIT_TEST
+#include "unittest.h"
+#endif
+
// Forward declarations
mDNSlocal void BeginSleepProcessing(mDNS *const m);
mDNSlocal void RetrySPSRegistrations(mDNS *const m);
mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAddr *EthAddr, mDNSOpaque48 *password, mDNSBool unicastOnly);
-mDNSlocal mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
mDNSlocal mDNSBool LocalRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
mDNSlocal void mDNS_PurgeForQuestion(mDNS *const m, DNSQuestion *q);
mDNSlocal void CheckForDNSSECRecords(mDNS *const m, DNSQuestion *q);
@@ -109,6 +117,10 @@ mDNSlocal mDNSu8 *GetValueForMACAddr(mDNSu8 *ptr, mDNSu8 *limit, mDNSEthAddr *et
#define NR_AnswerMulticast (mDNSu8*)~0
#define NR_AnswerUnicast (mDNSu8*)~1
+// Question default timeout values
+#define DEFAULT_MCAST_TIMEOUT 5
+#define DEFAULT_LO_OR_P2P_TIMEOUT 5
+
// The code (see SendQueries() and BuildQuestion()) needs to have the
// RequestUnicast value set to a value one greater than the number of times you want the query
// sent with the "request unicast response" (QU) bit set.
@@ -274,24 +286,27 @@ mDNSlocal AuthEntity *GetAuthEntity(AuthHash *r, const AuthGroup *const Preserve
return(e);
}
-mDNSexport AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name)
+mDNSexport AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 namehash, const domainname *const name)
{
AuthGroup *ag;
+ const mDNSu32 slot = namehash % AUTH_HASH_SLOTS;
+
for (ag = r->rrauth_hash[slot]; ag; ag=ag->next)
if (ag->namehash == namehash && SameDomainName(ag->name, name))
break;
return(ag);
}
-mDNSexport AuthGroup *AuthGroupForRecord(AuthHash *r, const mDNSu32 slot, const ResourceRecord *const rr)
+mDNSexport AuthGroup *AuthGroupForRecord(AuthHash *r, const ResourceRecord *const rr)
{
- return(AuthGroupForName(r, slot, rr->namehash, rr->name));
+ return(AuthGroupForName(r, rr->namehash, rr->name));
}
-mDNSlocal AuthGroup *GetAuthGroup(AuthHash *r, const mDNSu32 slot, const ResourceRecord *const rr)
+mDNSlocal AuthGroup *GetAuthGroup(AuthHash *r, const ResourceRecord *const rr)
{
mDNSu16 namelen = DomainNameLength(rr->name);
AuthGroup *ag = (AuthGroup*)GetAuthEntity(r, mDNSNULL);
+ const mDNSu32 slot = rr->namehash % AUTH_HASH_SLOTS;
if (!ag) { LogMsg("GetAuthGroup: Failed to allocate memory for %##s", rr->name->c); return(mDNSNULL); }
ag->next = r->rrauth_hash[slot];
ag->namehash = rr->namehash;
@@ -310,9 +325,9 @@ mDNSlocal AuthGroup *GetAuthGroup(AuthHash *r, const mDNSu32 slot, const Resourc
}
AssignDomainName(ag->name, rr->name);
- if (AuthGroupForRecord(r, slot, rr)) LogMsg("GetAuthGroup: Already have AuthGroup for %##s", rr->name->c);
+ if (AuthGroupForRecord(r, rr)) LogMsg("GetAuthGroup: Already have AuthGroup for %##s", rr->name->c);
r->rrauth_hash[slot] = ag;
- if (AuthGroupForRecord(r, slot, rr) != ag) LogMsg("GetAuthGroup: Not finding AuthGroup for %##s", rr->name->c);
+ if (AuthGroupForRecord(r, rr) != ag) LogMsg("GetAuthGroup: Not finding AuthGroup for %##s", rr->name->c);
return(ag);
}
@@ -320,11 +335,11 @@ mDNSlocal AuthGroup *GetAuthGroup(AuthHash *r, const mDNSu32 slot, const Resourc
// Returns the AuthGroup in which the AuthRecord was inserted
mDNSexport AuthGroup *InsertAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr)
{
- (void)m;
AuthGroup *ag;
- const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
- ag = AuthGroupForRecord(r, slot, &rr->resrec);
- if (!ag) ag = GetAuthGroup(r, slot, &rr->resrec); // If we don't have a AuthGroup for this name, make one now
+
+ (void)m;
+ ag = AuthGroupForRecord(r, &rr->resrec);
+ if (!ag) ag = GetAuthGroup(r, &rr->resrec); // If we don't have a AuthGroup for this name, make one now
if (ag)
{
*(ag->rrauth_tail) = rr; // Append this record to tail of cache slot list
@@ -337,9 +352,8 @@ mDNSexport AuthGroup *RemoveAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *r
{
AuthGroup *a;
AuthRecord **rp;
- const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
- a = AuthGroupForRecord(r, slot, &rr->resrec);
+ a = AuthGroupForRecord(r, &rr->resrec);
if (!a) { LogMsg("RemoveAuthRecord: ERROR!! AuthGroup not found for %s", ARDisplayString(m, rr)); return mDNSNULL; }
rp = &a->members;
while (*rp)
@@ -359,18 +373,19 @@ mDNSexport AuthGroup *RemoveAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *r
return a;
}
-mDNSexport CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name)
+mDNSexport CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 namehash, const domainname *const name)
{
CacheGroup *cg;
+ mDNSu32 slot = HashSlotFromNameHash(namehash);
for (cg = m->rrcache_hash[slot]; cg; cg=cg->next)
if (cg->namehash == namehash && SameDomainName(cg->name, name))
break;
return(cg);
}
-mDNSlocal CacheGroup *CacheGroupForRecord(const mDNS *const m, const mDNSu32 slot, const ResourceRecord *const rr)
+mDNSlocal CacheGroup *CacheGroupForRecord(const mDNS *const m, const ResourceRecord *const rr)
{
- return(CacheGroupForName(m, slot, rr->namehash, rr->name));
+ return(CacheGroupForName(m, rr->namehash, rr->name));
}
mDNSexport mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr)
@@ -472,7 +487,7 @@ 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
+#if AWD_METRICS
uDNSMetrics metrics;
#endif
@@ -496,7 +511,7 @@ 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 AWD_METRICS
if ((q->CNAMEReferrals == 0) && !q->metrics.originalQName)
{
domainname * qName;
@@ -532,7 +547,7 @@ 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
+#if AWD_METRICS
q->metrics = metrics;
#endif
if (sock)
@@ -787,7 +802,6 @@ mDNSlocal void AnswerAllLocalQuestionsWithLocalAuthRecord(mDNS *const m, AuthRec
(X) &kDNSRecordTypeActiveUniqueMask ? DefaultAnnounceIntervalForTypeUnique : 0)
#define TimeToAnnounceThisRecord(RR,time) ((RR)->AnnounceCount && (time) - ((RR)->LastAPTime + (RR)->ThisAPInterval) >= 0)
-#define TimeToSendThisRecord(RR,time) ((TimeToAnnounceThisRecord(RR,time) || (RR)->ImmedAnswer) && ResourceRecordIsValidAnswer(RR))
#define TicksTTL(RR) ((mDNSs32)(RR)->resrec.rroriginalttl * mDNSPlatformOneSecond)
#define RRExpireTime(RR) ((RR)->TimeRcvd + TicksTTL(RR))
@@ -962,9 +976,9 @@ mDNSlocal void InitializeLastAPTime(mDNS *const m, AuthRecord *const rr)
}
rr->LastAPTime = m->SuppressProbes - rr->ThisAPInterval;
}
- // Skip kDNSRecordTypeKnownUnique records here and set their LastAPTime in the "else" block below so that they get announced immediately,
- // otherwise, their announcement would be delayed until all other record probes complete.
- else if ((rr->resrec.RecordType != kDNSRecordTypeKnownUnique) && m->SuppressProbes && m->SuppressProbes - m->timenow >= 0)
+ // Skip kDNSRecordTypeKnownUnique and kDNSRecordTypeShared records here and set their LastAPTime in the "else" block below so
+ // that they get announced immediately, otherwise, their announcement would be delayed until the based on the SuppressProbes value.
+ else if ((rr->resrec.RecordType != kDNSRecordTypeKnownUnique) && (rr->resrec.RecordType != kDNSRecordTypeShared) && m->SuppressProbes && (m->SuppressProbes - m->timenow >= 0))
rr->LastAPTime = m->SuppressProbes - rr->ThisAPInterval + DefaultProbeIntervalForTypeUnique * DefaultProbeCountForTypeUnique + rr->ThisAPInterval / 2;
else
rr->LastAPTime = m->timenow - rr->ThisAPInterval;
@@ -1155,9 +1169,8 @@ mDNSlocal AuthRecord *CheckAuthIdenticalRecord(AuthHash *r, AuthRecord *rr)
{
const AuthGroup *a;
AuthRecord *rp;
- const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
- a = AuthGroupForRecord(r, slot, &rr->resrec);
+ a = AuthGroupForRecord(r, &rr->resrec);
if (!a) return mDNSNULL;
rp = a->members;
while (rp)
@@ -1181,9 +1194,8 @@ mDNSlocal mDNSBool CheckAuthRecordConflict(AuthHash *r, AuthRecord *rr)
{
const AuthGroup *a;
const AuthRecord *rp;
- const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
- a = AuthGroupForRecord(r, slot, &rr->resrec);
+ a = AuthGroupForRecord(r, &rr->resrec);
if (!a) return mDNSfalse;
rp = a->members;
while (rp)
@@ -1203,9 +1215,8 @@ mDNSlocal AuthRecord *CheckAuthSameRecord(AuthHash *r, AuthRecord *rr)
{
const AuthGroup *a;
AuthRecord *rp;
- const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
- a = AuthGroupForRecord(r, slot, &rr->resrec);
+ a = AuthGroupForRecord(r, &rr->resrec);
if (!a) return mDNSNULL;
rp = a->members;
while (rp)
@@ -1386,9 +1397,9 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
{
if (rr->resrec.RecordType == kDNSRecordTypeUnique)
rr->resrec.RecordType = kDNSRecordTypeVerified;
- else
+ else if (rr->resrec.RecordType != kDNSRecordTypeKnownUnique)
{
- LogMsg("mDNS_Register_internal: ERROR! %##s (%s): rr->DependentOn && RecordType != kDNSRecordTypeUnique",
+ LogMsg("mDNS_Register_internal: ERROR! %##s (%s): rr->DependentOn && RecordType != kDNSRecordTypeUnique or kDNSRecordTypeKnownUnique",
rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
return(mStatus_Invalid);
}
@@ -1630,7 +1641,7 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
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
- mDNSPlatformGetRemoteMacAddr(m, &raddr);
+ mDNSPlatformGetRemoteMacAddr(&raddr);
}
return(mStatus_NoError);
@@ -1679,9 +1690,8 @@ mDNSexport mStatus mDNS_Deregister_internal(mDNS *const m, AuthRecord *const rr,
{
AuthGroup *a;
AuthRecord **rp;
- const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
- a = AuthGroupForRecord(&m->rrauth, slot, &rr->resrec);
+ a = AuthGroupForRecord(&m->rrauth, &rr->resrec);
if (!a) return mDNSfalse;
rp = &a->members;
while (*rp && *rp != rr) rp=&(*rp)->next;
@@ -1954,6 +1964,27 @@ mDNSlocal void AddRecordToResponseList(AuthRecord ***nrpp, AuthRecord *rr, AuthR
debugf("AddRecordToResponseList: %##s (%s) already in list", rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
}
+mDNSlocal void AddRRSetAdditionalsToResponseList(mDNS *const m, AuthRecord ***nrpp, AuthRecord *rr, AuthRecord *additional, const mDNSInterfaceID InterfaceID)
+{
+ AuthRecord *rr2;
+ if (additional->resrec.RecordType & kDNSRecordTypeUniqueMask)
+ {
+ for (rr2 = m->ResourceRecords; rr2; rr2 = rr2->next)
+ {
+ if ((rr2->resrec.namehash == additional->resrec.namehash) &&
+ (rr2->resrec.rrtype == additional->resrec.rrtype) &&
+ (rr2 != additional) &&
+ (rr2->resrec.RecordType & kDNSRecordTypeUniqueMask) &&
+ (rr2->resrec.rrclass == additional->resrec.rrclass) &&
+ ResourceRecordIsValidInterfaceAnswer(rr2, InterfaceID) &&
+ SameDomainName(rr2->resrec.name, additional->resrec.name))
+ {
+ AddRecordToResponseList(nrpp, rr2, rr);
+ }
+ }
+ }
+}
+
mDNSlocal void AddAdditionalsToResponseList(mDNS *const m, AuthRecord *ResponseRecords, AuthRecord ***nrpp, const mDNSInterfaceID InterfaceID)
{
AuthRecord *rr, *rr2;
@@ -1962,10 +1993,16 @@ mDNSlocal void AddAdditionalsToResponseList(mDNS *const m, AuthRecord *ResponseR
// (Note: This is an "if", not a "while". If we add a record, we'll find it again
// later in the "for" loop, and we will follow further "additional" links then.)
if (rr->Additional1 && ResourceRecordIsValidInterfaceAnswer(rr->Additional1, InterfaceID))
+ {
AddRecordToResponseList(nrpp, rr->Additional1, rr);
+ AddRRSetAdditionalsToResponseList(m, nrpp, rr, rr->Additional1, InterfaceID);
+ }
if (rr->Additional2 && ResourceRecordIsValidInterfaceAnswer(rr->Additional2, InterfaceID))
+ {
AddRecordToResponseList(nrpp, rr->Additional2, rr);
+ AddRRSetAdditionalsToResponseList(m, nrpp, rr, rr->Additional2, InterfaceID);
+ }
// For SRV records, automatically add the Address record(s) for the target host
if (rr->resrec.rrtype == kDNSType_SRV)
@@ -2485,7 +2522,7 @@ mDNSlocal void SendResponses(mDNS *const m)
mDNSs32 maxExistingAnnounceInterval = 0;
const NetworkInterfaceInfo *intf = GetFirstActiveInterface(m->HostInterfaces);
- m->NextScheduledResponse = m->timenow + 0x78000000;
+ m->NextScheduledResponse = m->timenow + FutureTime;
if (m->SleepState == SleepState_Transferring) RetrySPSRegistrations(m);
@@ -3059,13 +3096,18 @@ mDNSexport void SetNextCacheCheckTimeForRecord(mDNS *const m, CacheRecord *const
verbosedebugf("SetNextCacheCheckTimeForRecord: NextRequiredQuery in %ld sec CacheCheckGracePeriod %d ticks for %s",
(rr->NextRequiredQuery - m->timenow) / mDNSPlatformOneSecond, CacheCheckGracePeriod(rr), CRDisplayString(m,rr));
}
- ScheduleNextCacheCheckTime(m, HashSlot(rr->resrec.name), NextCacheCheckEvent(rr));
+ ScheduleNextCacheCheckTime(m, HashSlotFromNameHash(rr->resrec.namehash), NextCacheCheckEvent(rr));
}
#define kMinimumReconfirmTime ((mDNSu32)mDNSPlatformOneSecond * 5)
#define kDefaultReconfirmTimeForWake ((mDNSu32)mDNSPlatformOneSecond * 5)
#define kDefaultReconfirmTimeForNoAnswer ((mDNSu32)mDNSPlatformOneSecond * 5)
-#define kDefaultReconfirmTimeForFlappingInterface ((mDNSu32)mDNSPlatformOneSecond * 5)
+
+// Delay before restarting questions on a flapping interface.
+#define kDefaultQueryDelayTimeForFlappingInterface ((mDNSu32)mDNSPlatformOneSecond * 3)
+// After kDefaultQueryDelayTimeForFlappingInterface seconds, allow enough time for up to three queries (0, 1, and 4 seconds)
+// plus three seconds for "response delay" before removing the reconfirmed records from the cache.
+#define kDefaultReconfirmTimeForFlappingInterface (kDefaultQueryDelayTimeForFlappingInterface + ((mDNSu32)mDNSPlatformOneSecond * 7))
mDNSexport mStatus mDNS_Reconfirm_internal(mDNS *const m, CacheRecord *const rr, mDNSu32 interval)
{
@@ -3080,7 +3122,7 @@ mDNSexport mStatus mDNS_Reconfirm_internal(mDNS *const m, CacheRecord *const rr,
// Add a 33% random amount to the interval, to avoid synchronization between multiple hosts
// For all the reconfirmations in a given batch, we want to use the same random value
// so that the reconfirmation questions can be grouped into a single query packet
- if (!m->RandomReconfirmDelay) m->RandomReconfirmDelay = 1 + mDNSRandom(0x3FFFFFFF);
+ if (!m->RandomReconfirmDelay) m->RandomReconfirmDelay = 1 + mDNSRandom(FutureTime);
interval += m->RandomReconfirmDelay % ((interval/3) + 1);
rr->TimeRcvd = m->timenow - (mDNSs32)interval * 3;
rr->resrec.rroriginalttl = (interval * 4 + mDNSPlatformOneSecond - 1) / mDNSPlatformOneSecond;
@@ -3110,8 +3152,7 @@ mDNSlocal mDNSBool BuildQuestion(mDNS *const m, const NetworkInterfaceInfo *intf
else
{
mDNSu32 forecast = *answerforecast + anoninfo_space;
- const mDNSu32 slot = HashSlot(&q->qname);
- const CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ const CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
CacheRecord *rr;
CacheRecord **ka = *kalistptrptr; // Make a working copy of the pointer we're going to update
@@ -3204,7 +3245,7 @@ mDNSlocal void ReconfirmAntecedents(mDNS *const m, const domainname *const name,
// to get a AAAA response is not grounds to doubt the PTR/SRV chain that lead us to that name.
mDNSlocal const CacheRecord *CacheHasAddressTypeForName(mDNS *const m, const domainname *const name, const mDNSu32 namehash)
{
- CacheGroup *const cg = CacheGroupForName(m, HashSlot(name), namehash, name);
+ CacheGroup *const cg = CacheGroupForName(m, namehash, name);
const CacheRecord *cr = cg ? cg->members : mDNSNULL;
while (cr && !RRTypeIsAddressType(cr->resrec.rrtype)) cr=cr->next;
return(cr);
@@ -3214,7 +3255,7 @@ mDNSlocal const CacheRecord *CacheHasAddressTypeForName(mDNS *const m, const dom
mDNSlocal const CacheRecord *FindSPSInCache1(mDNS *const m, const DNSQuestion *const q, const CacheRecord *const c0, const CacheRecord *const c1)
{
#ifndef SPC_DISABLED
- CacheGroup *const cg = CacheGroupForName(m, HashSlot(&q->qname), q->qnamehash, &q->qname);
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
const CacheRecord *cr, *bestcr = mDNSNULL;
mDNSu32 bestmetric = 1000000;
for (cr = cg ? cg->members : mDNSNULL; cr; cr=cr->next)
@@ -3365,7 +3406,7 @@ mDNSlocal void mDNSSendWakeOnResolve(mDNS *const m, DNSQuestion *q)
mDNSPlatformMemCopy(IPAddr, &d->c[i + 1], len - i);
IPAddr[len - i] = 0;
m->mDNSStats.WakeOnResolves++;
- mDNSPlatformSendWakeupPacket(m, InterfaceID, EthAddr, IPAddr, InitialWakeOnResolveCount - q->WakeOnResolveCount);
+ mDNSPlatformSendWakeupPacket(InterfaceID, EthAddr, IPAddr, InitialWakeOnResolveCount - q->WakeOnResolveCount);
return;
}
else if (d->c[i] == ':')
@@ -3386,8 +3427,7 @@ mDNSlocal mDNSBool AccelerateThisQuery(mDNS *const m, DNSQuestion *q)
{
// We forecast: qname (n) type (2) class (2)
mDNSu32 forecast = (mDNSu32)DomainNameLength(&q->qname) + 4;
- const mDNSu32 slot = HashSlot(&q->qname);
- const CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ const CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
const CacheRecord *rr;
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next) // If we have a resource record in our cache,
if (rr->resrec.rdlength <= SmallRecordLimit && // which is small enough to sensibly fit in the packet
@@ -3490,7 +3530,7 @@ mDNSlocal void SendQueries(mDNS *const m)
const mDNSu8 *const limit = m->omsg.data + sizeof(m->omsg.data);
// If we fail to get a new on-demand socket (should only happen cases of the most extreme resource exhaustion), we'll try again next time
- if (!q->LocalSocket) q->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
+ if (!q->LocalSocket) q->LocalSocket = mDNSPlatformUDPSocket(zeroIPPort);
if (q->LocalSocket)
{
InitializeDNSMessage(&m->omsg.h, q->TargetQID, QueryFlags);
@@ -3531,7 +3571,7 @@ mDNSlocal void SendQueries(mDNS *const m)
// Note: Don't set NextScheduledQuery until here, because uDNS_CheckCurrentQuestion in the loop above can add new questions to the list,
// which causes NextScheduledQuery to get (incorrectly) set to m->timenow. Setting it here is the right place, because the very
// next thing we do is scan the list and call SetNextQueryTime() for every question we find, so we know we end up with the right value.
- m->NextScheduledQuery = m->timenow + 0x78000000;
+ m->NextScheduledQuery = m->timenow + FutureTime;
for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
{
if (mDNSOpaque16IsZero(q->TargetQID)
@@ -3610,7 +3650,7 @@ mDNSlocal void SendQueries(mDNS *const m)
// 2. Scan our authoritative RR list to see what probes we might need to send
- m->NextScheduledProbe = m->timenow + 0x78000000;
+ m->NextScheduledProbe = m->timenow + FutureTime;
if (m->CurrentRecord)
LogMsg("SendQueries ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
@@ -4110,7 +4150,7 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
return;
}
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
if ((AddRecord == QC_add) && Question_uDNS(q) && !followcname)
{
const domainname * queryName;
@@ -4169,6 +4209,11 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
if (rr->DelayDelivery) return; // We'll come back later when CacheRecordDeferredAdd() calls us
+#if USE_DNS64
+ // If DNS64StateMachine() returns true, then the question was restarted as a different question, so return.
+ if (!mDNSOpaque16IsZero(q->TargetQID) && DNS64StateMachine(m, q, &rr->resrec, AddRecord)) return;
+#endif
+
#ifdef USE_LIBIDN
if (rr->resrec.RecordType == kDNSRecordTypePacketNegative) // If negative answer, check if we need to try Punycode conversion
{
@@ -4209,7 +4254,18 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
q->QuestionCallback(m, q, &neg.resrec, AddRecord);
}
else
- q->QuestionCallback(m, q, &rr->resrec, AddRecord);
+ {
+#if USE_DNS64
+ if (DNS64ShouldAnswerQuestion(q, &rr->resrec))
+ {
+ DNS64AnswerQuestion(m, q, &rr->resrec, AddRecord);
+ }
+ else
+#endif
+ {
+ q->QuestionCallback(m, q, &rr->resrec, AddRecord);
+ }
+ }
mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
}
// If this is an "Add" operation and this question needs validation, validate the response.
@@ -4265,12 +4321,12 @@ mDNSlocal void CacheRecordDeferredAdd(mDNS *const m, CacheRecord *rr)
m->CurrentQuestion = mDNSNULL;
}
-mDNSlocal mDNSs32 CheckForSoonToExpireRecords(mDNS *const m, const domainname *const name, const mDNSu32 namehash, const mDNSu32 slot, mDNSBool *purge)
+mDNSlocal mDNSs32 CheckForSoonToExpireRecords(mDNS *const m, const domainname *const name, const mDNSu32 namehash, mDNSBool *purge)
{
const mDNSs32 threshhold = m->timenow + mDNSPlatformOneSecond; // See if there are any records expiring within one second
const mDNSs32 start = m->timenow - 0x10000000;
mDNSs32 delay = start;
- CacheGroup *cg = CacheGroupForName(m, slot, namehash, name);
+ CacheGroup *cg = CacheGroupForName(m, namehash, name);
const CacheRecord *rr;
if (purge)
@@ -4559,13 +4615,12 @@ mDNSlocal void ReleaseAdditionalCacheRecords(mDNS *const m, CacheRecord **rp)
mDNSexport void ReleaseCacheRecord(mDNS *const m, CacheRecord *r)
{
CacheGroup *cg;
- const mDNSu32 slot = HashSlot(r->resrec.name);
//LogMsg("ReleaseCacheRecord: Releasing %s", CRDisplayString(m, r));
if (r->resrec.rdata && r->resrec.rdata != (RData*)&r->smallrdatastorage) mDNSPlatformMemFree(r->resrec.rdata);
r->resrec.rdata = mDNSNULL;
- cg = CacheGroupForRecord(m, slot, &r->resrec);
+ cg = CacheGroupForRecord(m, &r->resrec);
if (!cg)
{
@@ -4662,7 +4717,7 @@ mDNSlocal void CheckCacheExpiration(mDNS *const m, const mDNSu32 slot, CacheGrou
m->NextScheduledQuery = m->timenow;
// After sending the query we'll increment UnansweredQueries and call SetNextCacheCheckTimeForRecord(),
// which will correctly update m->NextCacheCheck for us.
- event = m->timenow + 0x3FFFFFFF;
+ event = m->timenow + FutureTime;
}
}
}
@@ -4687,15 +4742,13 @@ mDNSlocal void CheckCacheExpiration(mDNS *const m, const mDNSu32 slot, CacheGrou
// returns true to indicate the same.
mDNSlocal mDNSBool AnswerQuestionWithLORecord(mDNS *const m, DNSQuestion *q, mDNSBool checkOnly)
{
- mDNSu32 slot;
AuthRecord *lr;
AuthGroup *ag;
if (m->CurrentRecord)
LogMsg("AnswerQuestionWithLORecord ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
- slot = AuthHashSlot(&q->qname);
- ag = AuthGroupForName(&m->rrauth, slot, q->qnamehash, &q->qname);
+ ag = AuthGroupForName(&m->rrauth, q->qnamehash, &q->qname);
if (ag)
{
m->CurrentRecord = ag->members;
@@ -4772,8 +4825,19 @@ mDNSlocal mDNSBool AnswerQuestionWithLORecord(mDNS *const m, DNSQuestion *q, mDN
// reasons for suppressing the query, this function should be updated.
mDNSlocal void AnswerSuppressedQuestion(mDNS *const m, DNSQuestion *q)
{
- mDNSBool SuppressQuery = q->SuppressQuery;
- mDNSBool DisallowPID = q->DisallowPID;
+ mDNSBool SuppressQuery;
+ mDNSBool DisallowPID;
+
+ // If the client did not set the kDNSServiceFlagsReturnIntermediates flag, then don't generate a negative response, just
+ // deactivate the DNSQuestion.
+ if (!q->ReturnIntermed)
+ {
+ q->ThisQInterval = 0;
+ return;
+ }
+
+ SuppressQuery = q->SuppressQuery;
+ DisallowPID = q->DisallowPID;
// make sure that QuerySuppressed() returns false
q->SuppressQuery = mDNSfalse;
@@ -4789,13 +4853,15 @@ mDNSlocal void AnswerNewQuestion(mDNS *const m)
{
mDNSBool ShouldQueryImmediately = mDNStrue;
DNSQuestion *const q = m->NewQuestions; // Grab the question we're going to answer
- mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+#if USE_DNS64
+ if (!mDNSOpaque16IsZero(q->TargetQID)) DNS64HandleNewQuestion(m, q);
+#endif
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
mDNSBool AnsweredFromCache = mDNSfalse;
verbosedebugf("AnswerNewQuestion: Answering %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
- if (cg) CheckCacheExpiration(m, slot, cg);
+ if (cg) CheckCacheExpiration(m, HashSlotFromNameHash(q->qnamehash), cg);
if (m->NewQuestions != q) { LogInfo("AnswerNewQuestion: Question deleted while doing CheckCacheExpiration"); goto exit; }
m->NewQuestions = q->next;
// Advance NewQuestions to the next *after* calling CheckCacheExpiration, because if we advance it first
@@ -4935,11 +5001,10 @@ exit:
// appropriate answers, stopping if it reaches a NewLocalOnlyRecord -- these will be handled by AnswerAllLocalQuestionsWithLocalAuthRecord
mDNSlocal void AnswerNewLocalOnlyQuestion(mDNS *const m)
{
- mDNSu32 slot;
AuthGroup *ag;
DNSQuestion *q = m->NewLocalOnlyQuestions; // Grab the question we're going to answer
- m->NewLocalOnlyQuestions = q->next; // Advance NewLocalOnlyQuestions to the next (if any)
mDNSBool retEv = mDNSfalse;
+ m->NewLocalOnlyQuestions = q->next; // Advance NewLocalOnlyQuestions to the next (if any)
debugf("AnswerNewLocalOnlyQuestion: Answering %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
@@ -4954,8 +5019,7 @@ mDNSlocal void AnswerNewLocalOnlyQuestion(mDNS *const m)
// 1. First walk the LocalOnly records answering the LocalOnly question
// 2. As LocalOnly questions should also be answered by any other Auth records local to the machine,
// walk the ResourceRecords list delivering the answers
- slot = AuthHashSlot(&q->qname);
- ag = AuthGroupForName(&m->rrauth, slot, q->qnamehash, &q->qname);
+ ag = AuthGroupForName(&m->rrauth, q->qnamehash, &q->qname);
if (ag)
{
m->CurrentRecord = ag->members;
@@ -5120,9 +5184,9 @@ mDNSlocal CacheGroup *GetCacheGroup(mDNS *const m, const mDNSu32 slot, const Res
}
AssignDomainName(cg->name, rr->name);
- if (CacheGroupForRecord(m, slot, rr)) LogMsg("GetCacheGroup: Already have CacheGroup for %##s", rr->name->c);
+ if (CacheGroupForRecord(m, rr)) LogMsg("GetCacheGroup: Already have CacheGroup for %##s", rr->name->c);
m->rrcache_hash[slot] = cg;
- if (CacheGroupForRecord(m, slot, rr) != cg) LogMsg("GetCacheGroup: Not finding CacheGroup for %##s", rr->name->c);
+ if (CacheGroupForRecord(m, rr) != cg) LogMsg("GetCacheGroup: Not finding CacheGroup for %##s", rr->name->c);
return(cg);
}
@@ -5162,7 +5226,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->SPSProxyListChanged); \
m->SPSProxyListChanged = (X); } while(0)
// Called from mDNS_Execute() to expire stale proxy records
@@ -5221,13 +5285,12 @@ mDNSlocal void CheckRmvEventsForLocalRecords(mDNS *const m)
}
}
-mDNSlocal void TimeoutQuestions(mDNS *const m)
+mDNSlocal void TimeoutQuestions_internal(mDNS *const m, DNSQuestion* questions, mDNSInterfaceID InterfaceID)
{
- m->NextScheduledStopTime = m->timenow + 0x3FFFFFFF;
if (m->CurrentQuestion)
LogMsg("TimeoutQuestions ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c,
DNSTypeName(m->CurrentQuestion->qtype));
- m->CurrentQuestion = m->Questions;
+ m->CurrentQuestion = questions;
while (m->CurrentQuestion)
{
DNSQuestion *const q = m->CurrentQuestion;
@@ -5239,7 +5302,8 @@ mDNSlocal void TimeoutQuestions(mDNS *const m)
if (m->timenow - q->StopTime >= 0)
{
LogInfo("TimeoutQuestions: question %p %##s timed out, time %d", q, q->qname.c, m->timenow - q->StopTime);
- GenerateNegativeResponse(m, mDNSInterface_Any, QC_forceresponse);
+ q->LOAddressAnswers = 0; // unset since timing out the question
+ GenerateNegativeResponse(m, InterfaceID, QC_forceresponse);
if (m->CurrentQuestion == q) q->StopTime = 0;
}
else
@@ -5257,6 +5321,13 @@ mDNSlocal void TimeoutQuestions(mDNS *const m)
m->CurrentQuestion = mDNSNULL;
}
+mDNSlocal void TimeoutQuestions(mDNS *const m)
+{
+ m->NextScheduledStopTime = m->timenow + FutureTime; // push reschedule of TimeoutQuestions to way off into the future
+ TimeoutQuestions_internal(m, m->Questions, mDNSInterface_Any);
+ TimeoutQuestions_internal(m, m->LocalOnlyQuestions, mDNSInterface_LocalOnly);
+}
+
mDNSlocal void mDNSCoreFreeProxyRR(mDNS *const m)
{
AuthRecord *rrPtr = m->SPSRRSet, *rrNext = mDNSNULL;
@@ -5274,10 +5345,6 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
{
mDNS_Lock(m); // Must grab lock before trying to read m->timenow
-#if APPLE_OSX_mDNSResponder
- mDNSLogStatistics(m);
-#endif // APPLE_OSX_mDNSResponder
-
if (m->timenow - m->NextScheduledEvent >= 0)
{
int i;
@@ -5304,13 +5371,13 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
if (m->rrcache_size && m->timenow - m->NextCacheCheck >= 0)
{
mDNSu32 numchecked = 0;
- m->NextCacheCheck = m->timenow + 0x3FFFFFFF;
+ m->NextCacheCheck = m->timenow + FutureTime;
for (slot = 0; slot < CACHE_HASH_SLOTS; slot++)
{
if (m->timenow - m->rrcache_nextcheck[slot] >= 0)
{
CacheGroup **cp = &m->rrcache_hash[slot];
- m->rrcache_nextcheck[slot] = m->timenow + 0x3FFFFFFF;
+ m->rrcache_nextcheck[slot] = m->timenow + FutureTime;
while (*cp)
{
debugf("m->NextCacheCheck %4d Slot %3d %##s", numchecked, slot, *cp ? (*cp)->name : (domainname*)"\x04NULL");
@@ -5330,7 +5397,7 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
if (m->timenow - m->NextScheduledSPS >= 0)
{
- m->NextScheduledSPS = m->timenow + 0x3FFFFFFF;
+ m->NextScheduledSPS = m->timenow + FutureTime;
CheckProxyRecords(m, m->DuplicateRecords); // Clear m->DuplicateRecords first, then m->ResourceRecords
CheckProxyRecords(m, m->ResourceRecords);
}
@@ -5341,7 +5408,7 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
// as records could have expired during that check
if (m->timenow - m->NextScheduledKA >= 0)
{
- m->NextScheduledKA = m->timenow + 0x3FFFFFFF;
+ m->NextScheduledKA = m->timenow + FutureTime;
mDNS_SendKeepalives(m);
}
@@ -5525,16 +5592,17 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
m->RandomQueryDelay = 0;
m->RandomReconfirmDelay = 0;
+ // See if any questions (or local-only questions) have timed out
if (m->NextScheduledStopTime && m->timenow - m->NextScheduledStopTime >= 0) TimeoutQuestions(m);
#ifndef UNICAST_DISABLED
if (m->NextSRVUpdate && m->timenow - m->NextSRVUpdate >= 0) UpdateAllSRVRecords(m);
if (m->timenow - m->NextScheduledNATOp >= 0) CheckNATMappings(m);
if (m->timenow - m->NextuDNSEvent >= 0) uDNS_Tasks(m);
#endif
-#if APPLE_OSX_mDNSResponder
+#if APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
extern void serviceBLE();
if (m->NextBLEServiceTime && (m->timenow - m->NextBLEServiceTime >= 0)) serviceBLE();
-#endif // APPLE_OSX_mDNSResponder
+#endif // APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
}
// Note about multi-threaded systems:
@@ -5574,11 +5642,9 @@ mDNSlocal void SuspendLLQs(mDNS *m)
mDNSlocal mDNSBool QuestionHasLocalAnswers(mDNS *const m, DNSQuestion *q)
{
AuthRecord *rr;
- mDNSu32 slot;
AuthGroup *ag;
- slot = AuthHashSlot(&q->qname);
- ag = AuthGroupForName(&m->rrauth, slot, q->qnamehash, &q->qname);
+ ag = AuthGroupForName(&m->rrauth, q->qnamehash, &q->qname);
if (ag)
{
for (rr = ag->members; rr; rr=rr->next)
@@ -5614,7 +5680,7 @@ mDNSlocal void ActivateUnicastQuery(mDNS *const m, DNSQuestion *const question,
!SameDomainLabel(question->qname.c, (const mDNSu8 *)"\x0c_autotunnel6")&& question->QuestionCallback != AutoTunnelCallback)
{
question->NoAnswer = NoAnswer_Suspended;
- AddNewClientTunnel(m, question);
+ AddNewClientTunnel(question);
return;
}
#endif // APPLE_OSX_mDNSResponder
@@ -5890,7 +5956,7 @@ mDNSexport void mDNS_UpdateAllowSleep(mDNS *const m)
}
// Call the platform code to enable/disable sleep
- mDNSPlatformSetAllowSleep(m, allowSleep, reason);
+ mDNSPlatformSetAllowSleep(allowSleep, reason);
#else
(void) m;
#endif /* !defined(IDLESLEEPCONTROL_DISABLED) */
@@ -6001,7 +6067,7 @@ mDNSexport mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkIn
// now, then we don't update the DNS NULL record. But we do not prevent it from registering with the SPS. When SPS sees
// this DNS NULL record, it does not send any keepalives as it does not have all the information
mDNSPlatformMemZero(&mti, sizeof (mDNSTCPInfo));
- ret = mDNSPlatformRetrieveTCPInfo(m, &laddr, &lport, &raddr, &rport, &mti);
+ ret = mDNSPlatformRetrieveTCPInfo(&laddr, &lport, &raddr, &rport, &mti);
if (ret != mStatus_NoError)
{
LogMsg("mDNSPlatformRetrieveTCPInfo: mDNSPlatformRetrieveTCPInfo failed %d", ret);
@@ -6568,15 +6634,14 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
m->NextScheduledSPRetry = m->timenow;
+ // Clear out the SCDynamic entry that stores the external SPS information
+ mDNSPlatformClearSPSData();
+
if (!m->SystemWakeOnLANEnabled) LogSPS("BeginSleepProcessing: m->SystemWakeOnLANEnabled is false");
else if (!mDNSCoreHaveAdvertisedMulticastServices(m)) LogSPS("BeginSleepProcessing: No advertised services");
else // If we have at least one advertised service
{
NetworkInterfaceInfo *intf;
-
- // Clear out the SCDynamic entry that stores the external SPS information
- mDNSPlatformClearSPSData();
-
for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
{
// Intialize it to false. These values make sense only when SleepState is set to Sleeping.
@@ -6616,7 +6681,7 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
else if (SupportsInNICProxy(intf))
{
mDNSBool keepaliveOnly = mDNSfalse;
- if (ActivateLocalProxy(m, intf, &keepaliveOnly) == mStatus_NoError)
+ if (ActivateLocalProxy(intf, &keepaliveOnly) == mStatus_NoError)
{
SendGoodbyesForWakeOnlyService(m, &WakeOnlyService);
@@ -6833,11 +6898,6 @@ mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleep)
// 2. Re-validate our cache records
currtime = mDNSPlatformUTC();
-#if APPLE_OSX_mDNSResponder
- // start time of this statistics gathering interval
- m->StatStartTime = currtime;
-#endif // APPLE_OSX_mDNSResponder
-
diff = currtime - m->TimeSlept;
FORALL_CACHERECORDS(slot, cg, cr)
{
@@ -6984,7 +7044,7 @@ mDNSexport mDNSBool mDNSCoreReadyForSleep(mDNS *m, mDNSs32 now)
if (rr->state == regState_Refresh && rr->tcp)
{ LogSPS("mDNSCoreReadyForSleep: waiting for Record updateIntID 0x%x 0x%x (updateid %d) %s", rr->updateIntID.l[1], rr->updateIntID.l[0], mDNSVal16(rr->updateid), ARDisplayString(m,rr)); goto notready; }
#if APPLE_OSX_mDNSResponder
- if (!RecordReadyForSleep(m, rr)) { LogSPS("mDNSCoreReadyForSleep: waiting for %s", ARDisplayString(m, rr)); goto notready; }
+ if (!RecordReadyForSleep(rr)) { LogSPS("mDNSCoreReadyForSleep: waiting for %s", ARDisplayString(m, rr)); goto notready; }
#endif
}
@@ -7315,8 +7375,7 @@ exit:
mDNSlocal CacheRecord *FindIdenticalRecordInCache(const mDNS *const m, const ResourceRecord *const pktrr)
{
- mDNSu32 slot = HashSlot(pktrr->name);
- CacheGroup *cg = CacheGroupForRecord(m, slot, pktrr);
+ CacheGroup *cg = CacheGroupForRecord(m, pktrr);
CacheRecord *rr;
mDNSBool match;
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
@@ -7563,7 +7622,7 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
// We only mark this question for sending if it is at least one second since the last time we multicast it
// on this interface. If it is more than a second, or LastMCInterface is different, then we may multicast it.
// This is to guard against the case where someone blasts us with queries as fast as they can.
- if (m->timenow - (rr->LastMCTime + mDNSPlatformOneSecond) >= 0 ||
+ if ((mDNSu32)(m->timenow - rr->LastMCTime) >= (mDNSu32)mDNSPlatformOneSecond ||
(rr->LastMCInterface != mDNSInterfaceMark && rr->LastMCInterface != InterfaceID))
rr->NR_AnswerTo = NR_AnswerMulticast;
}
@@ -7592,44 +7651,25 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
if (query->h.flags.b[0] & kDNSFlag0_TC)
m->mDNSStats.KnownAnswerMultiplePkts++;
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- if (QuestionNeedsMulticastResponse)
-#else
// We only do the following accelerated cache expiration and duplicate question suppression processing
// for non-truncated multicast queries with multicast responses.
// For any query generating a unicast response we don't do this because we can't assume we will see the response.
// For truncated queries we don't do this because a response we're expecting might be suppressed by a subsequent
// known-answer packet, and when there's packet loss we can't safely assume we'll receive *all* known-answer packets.
if (QuestionNeedsMulticastResponse && !(query->h.flags.b[0] & kDNSFlag0_TC))
-#endif
{
#if POOF_ENABLED
- const mDNSu32 slot = HashSlot(&pktq.qname);
- CacheGroup *cg = CacheGroupForName(m, slot, pktq.qnamehash, &pktq.qname);
+ CacheGroup *cg = CacheGroupForName(m, pktq.qnamehash, &pktq.qname);
CacheRecord *cr;
// Make a list indicating which of our own cache records we expect to see updated as a result of this query
// Note: Records larger than 1K are not habitually multicast, so don't expect those to be updated
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- if (!(query->h.flags.b[0] & kDNSFlag0_TC))
-#endif // ENABLE_MULTI_PACKET_QUERY_SNOOPING
for (cr = cg ? cg->members : mDNSNULL; cr; cr=cr->next)
if (SameNameRecordAnswersQuestion(&cr->resrec, &pktq) && cr->resrec.rdlength <= SmallRecordLimit)
if (!cr->NextInKAList && eap != &cr->NextInKAList)
{
*eap = cr;
eap = &cr->NextInKAList;
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- if (cr->MPUnansweredQ == 0 || m->timenow - cr->MPLastUnansweredQT >= mDNSPlatformOneSecond)
- {
- // Although MPUnansweredQ is only really used for multi-packet query processing,
- // we increment it for both single-packet and multi-packet queries, so that it stays in sync
- // with the MPUnansweredKA value, which by necessity is incremented for both query types.
- cr->MPUnansweredQ++;
- cr->MPLastUnansweredQT = m->timenow;
- cr->MPExpectingKA = mDNStrue;
- }
-#endif // ENABLE_MULTI_PACKET_QUERY_SNOOPING
}
#endif // POOF_ENABLED
@@ -7637,9 +7677,6 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
// We only do this for non-truncated queries. Right now it would be too complicated to try
// to keep track of duplicate suppression state between multiple packets, especially when we
// can't guarantee to receive all of the Known Answer packets that go with a particular query.
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- if (!(query->h.flags.b[0] & kDNSFlag0_TC))
-#endif
// For anonymous question, the duplicate suppressesion should happen if the
// question belongs in the same group. As the group is expected to be
// small, we don't do the optimization for now.
@@ -7723,16 +7760,6 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
ourcacherr = FindIdenticalRecordInCache(m, &m->rec.r.resrec);
- #if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- // See if this Known-Answer suppresses any answers we were expecting for our cache records. We do this always,
- // even if the TC bit is not set (the TC bit will *not* be set in the *last* packet of a multi-packet KA list).
- if (ourcacherr && ourcacherr->MPExpectingKA && m->timenow - ourcacherr->MPLastUnansweredQT < mDNSPlatformOneSecond)
- {
- ourcacherr->MPUnansweredKA++;
- ourcacherr->MPExpectingKA = mDNSfalse;
- }
- #endif
-
#if POOF_ENABLED
// Having built our ExpectedAnswers list from the questions in this packet, we then remove
// any records that are suppressed by the Known Answer list in this packet.
@@ -7779,13 +7806,9 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
mDNSBool SendMulticastResponse = mDNSfalse; // Send modern multicast response
mDNSBool SendUnicastResponse = mDNSfalse; // Send modern unicast response (not legacy unicast response)
-#if !TARGET_OS_EMBEDDED
- // always honor kDNSQClass_UnicastResponse in embedded environment to increase reliability
- // in high multicast packet loss environments.
-
// If it's been one TTL/4 since we multicast this, then send a multicast response
// for conflict detection, etc.
- if (m->timenow - (rr->LastMCTime + TicksTTL(rr)/4) >= 0)
+ if ((mDNSu32)(m->timenow - rr->LastMCTime) >= (mDNSu32)TicksTTL(rr)/4)
{
SendMulticastResponse = mDNStrue;
// If this record was marked for modern (delayed) unicast response, then mark it as promoted to
@@ -7797,7 +7820,6 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
rr->NR_AnswerTo = NR_AnswerMulticast;
}
}
-#endif // !TARGET_OS_EMBEDDED
// If the client insists on a multicast response, then we'd better send one
if (rr->NR_AnswerTo == NR_AnswerMulticast)
@@ -7925,12 +7947,7 @@ exit:
cr->UnansweredQueries++;
cr->LastUnansweredTime = m->timenow;
if (cr->UnansweredQueries > 1)
- #if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- debugf("ProcessQuery: (!TC) UAQ %lu MPQ %lu MPKA %lu %s",
- cr->UnansweredQueries, cr->MPUnansweredQ, cr->MPUnansweredKA, CRDisplayString(m, cr));
- #else
debugf("ProcessQuery: UnansweredQueries %lu %s", cr->UnansweredQueries, CRDisplayString(m, cr));
- #endif // ENABLE_MULTI_PACKET_QUERY_SNOOPING
SetNextCacheCheckTimeForRecord(m, cr);
}
@@ -7940,49 +7957,12 @@ exit:
{
// Only show debugging message if this record was not about to expire anyway
if (RRExpireTime(cr) - m->timenow > (mDNSs32) kDefaultReconfirmTimeForNoAnswer * 4 / 3 + mDNSPlatformOneSecond)
- #if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- debugf("ProcessQuery: (Max) UAQ %lu MPQ %lu MPKA %lu mDNS_Reconfirm() for %s",
- cr->UnansweredQueries, cr->MPUnansweredQ, cr->MPUnansweredKA, CRDisplayString(m, cr));
- #else
- LogInfo("ProcessQuery: UnansweredQueries %lu TTL %lu mDNS_Reconfirm() for %s",
- cr->UnansweredQueries, (RRExpireTime(cr) - m->timenow + mDNSPlatformOneSecond-1) / mDNSPlatformOneSecond, CRDisplayString(m, cr));
- #endif // ENABLE_MULTI_PACKET_QUERY_SNOOPING
+ LogInfo("ProcessQuery: UnansweredQueries %lu interface %lu TTL %lu mDNS_Reconfirm() for %s",
+ cr->UnansweredQueries, InterfaceID, (RRExpireTime(cr) - m->timenow + mDNSPlatformOneSecond-1) / mDNSPlatformOneSecond, CRDisplayString(m, cr));
m->mDNSStats.PoofCacheDeletions++;
mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForNoAnswer);
}
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- // Make a guess, based on the multi-packet query / known answer counts, whether we think we
- // should have seen an answer for this. (We multiply MPQ by 4 and MPKA by 5, to allow for
- // possible packet loss of up to 20% of the additional KA packets.)
- else if (cr->MPUnansweredQ * 4 > cr->MPUnansweredKA * 5 + 8)
- {
- // We want to do this conservatively.
- // If there are so many machines on the network that they have to use multi-packet known-answer lists,
- // then we don't want them to all hit the network simultaneously with their final expiration queries.
- // By setting the record to expire in four minutes, we achieve two things:
- // (a) the 90-95% final expiration queries will be less bunched together
- // (b) we allow some time for us to witness enough other failed queries that we don't have to do our own
- mDNSu32 remain = (mDNSu32)(RRExpireTime(cr) - m->timenow) / 4;
- if (remain > 240 * (mDNSu32)mDNSPlatformOneSecond)
- remain = 240 * (mDNSu32)mDNSPlatformOneSecond;
-
- // Only show debugging message if this record was not about to expire anyway
- if (RRExpireTime(cr) - m->timenow > 4 * mDNSPlatformOneSecond)
- debugf("ProcessQuery: (MPQ) UAQ %lu MPQ %lu MPKA %lu mDNS_Reconfirm() for %s",
- cr->UnansweredQueries, cr->MPUnansweredQ, cr->MPUnansweredKA, CRDisplayString(m, cr));
-
- if (remain <= 60 * (mDNSu32)mDNSPlatformOneSecond)
- cr->UnansweredQueries++; // Treat this as equivalent to one definite unanswered query
- cr->MPUnansweredQ = 0; // Clear MPQ/MPKA statistics
- cr->MPUnansweredKA = 0;
- cr->MPExpectingKA = mDNSfalse;
-
- if (remain < kDefaultReconfirmTimeForNoAnswer)
- remain = kDefaultReconfirmTimeForNoAnswer;
- mDNS_Reconfirm_internal(m, cr, remain);
- }
-#endif // ENABLE_MULTI_PACKET_QUERY_SNOOPING
}
#endif // POOF_ENABLED
@@ -8229,19 +8209,13 @@ mDNSlocal void RefreshCacheRecord(mDNS *const m, CacheRecord *rr, mDNSu32 ttl)
rr->TimeRcvd = m->timenow;
rr->resrec.rroriginalttl = ttl;
rr->UnansweredQueries = 0;
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- rr->MPUnansweredQ = 0;
- rr->MPUnansweredKA = 0;
- rr->MPExpectingKA = mDNSfalse;
-#endif
SetNextCacheCheckTimeForRecord(m, rr);
}
mDNSexport void GrantCacheExtensions(mDNS *const m, DNSQuestion *q, mDNSu32 lease)
{
CacheRecord *rr;
- const mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ CacheGroup *cg = CacheGroupForName(m, q->qnamehash, &q->qname);
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
if (rr->CRActiveQuestion == q)
{
@@ -8454,8 +8428,7 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q, !dstaddr)))
{
CacheRecord *rr, *neg = mDNSNULL;
- mDNSu32 slot = HashSlot(&q.qname);
- CacheGroup *cg = CacheGroupForName(m, slot, q.qnamehash, &q.qname);
+ CacheGroup *cg = CacheGroupForName(m, q.qnamehash, &q.qname);
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
if (SameNameRecordAnswersQuestion(&rr->resrec, qptr))
{
@@ -8524,8 +8497,7 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
ptr = GetLargeResourceRecord(m, response, ptr, end, InterfaceID, kDNSRecordTypePacketAuth, &m->rec);
if (ptr && m->rec.r.resrec.RecordType != kDNSRecordTypePacketNegative && m->rec.r.resrec.rrtype == kDNSType_SOA)
{
- const mDNSu32 s = HashSlot(m->rec.r.resrec.name);
- CacheGroup *cgSOA = CacheGroupForRecord(m, s, &m->rec.r.resrec);
+ CacheGroup *cgSOA = CacheGroupForRecord(m, &m->rec.r.resrec);
const rdataSOA *const soa = (const rdataSOA *)m->rec.r.resrec.rdata->u.data;
mDNSu32 ttl_s = soa->min;
// We use the lesser of the SOA.MIN field and the SOA record's TTL, *except*
@@ -8537,7 +8509,7 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
// Create the SOA record as we may have to return this to the questions
// that we are acting as a proxy for currently or in the future.
- SOARecord = CreateNewCacheEntry(m, s, cgSOA, 1, mDNSfalse, mDNSNULL);
+ SOARecord = CreateNewCacheEntry(m, HashSlotFromNameHash(m->rec.r.resrec.namehash), cgSOA, 1, mDNSfalse, mDNSNULL);
// Special check for SOA queries: If we queried for a.b.c.d.com, and got no answer,
// with an Authority Section SOA record for d.com, then this is a hint that the authority
@@ -8620,12 +8592,12 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
// been NULL. If we pass NULL cg to new cache entries that we create below,
// it will create additional cache groups for the same name. To avoid that,
// look up the cache group again to re-initialize cg again.
- cg = CacheGroupForName(m, slot, hash, name);
+ cg = CacheGroupForName(m, hash, name);
if (NSECRecords && DNSSECQuestion(qptr))
{
// Create the cache entry with delay and then add the NSEC records
// to it and add it immediately.
- negcr = CreateNewCacheEntry(m, slot, cg, 1, mDNStrue, mDNSNULL);
+ negcr = CreateNewCacheEntry(m, HashSlotFromNameHash(hash), cg, 1, mDNStrue, mDNSNULL);
if (negcr)
{
negcr->CRDNSSECQuestion = 0;
@@ -8650,7 +8622,7 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
else
{
// Need to add with a delay so that we can tag the SOA record
- negcr = CreateNewCacheEntry(m, slot, cg, 1, mDNStrue, mDNSNULL);
+ negcr = CreateNewCacheEntry(m, HashSlotFromNameHash(hash), cg, 1, mDNStrue, mDNSNULL);
if (negcr)
{
negcr->CRDNSSECQuestion = 0;
@@ -8674,9 +8646,6 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
repeat--;
name = (const domainname *)(name->c + 1 + name->c[0]);
hash = DomainNameHashValue(name);
- slot = HashSlot(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);
}
}
}
@@ -8891,7 +8860,6 @@ mDNSlocal void mDNSParseNSEC3Records(mDNS *const m, const DNSMessage *const resp
}
for (i = 0; i < response->h.numAuthorities && ptr && ptr < end; i++)
{
- mDNSu32 slot;
CacheGroup *cg;
ptr = GetLargeResourceRecord(m, response, ptr, end, InterfaceID, kDNSRecordTypePacketAuth, &m->rec);
@@ -8901,11 +8869,10 @@ mDNSlocal void mDNSParseNSEC3Records(mDNS *const m, const DNSMessage *const resp
m->rec.r.resrec.RecordType = 0;
continue;
}
- slot = HashSlot(m->rec.r.resrec.name);
- cg = CacheGroupForRecord(m, slot, &m->rec.r.resrec);
+ cg = CacheGroupForRecord(m, &m->rec.r.resrec);
// Create the cache entry but don't add it to the cache it. We need
// to cache this along with the main cache record.
- rr = CreateNewCacheEntry(m, slot, cg, 0, mDNSfalse, mDNSNULL);
+ rr = CreateNewCacheEntry(m, HashSlotFromNameHash(m->rec.r.resrec.namehash), cg, 0, mDNSfalse, mDNSNULL);
if (rr)
{
debugf("mDNSParseNSEC3Records: %s", CRDisplayString(m, rr));
@@ -9027,8 +8994,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
CacheRecord *rr;
// Remember the unicast question that we found, which we use to make caching
// decisions later on in this function
- const mDNSu32 slot = HashSlot(&q.qname);
- CacheGroup *cg = CacheGroupForName(m, slot, q.qnamehash, &q.qname);
+ CacheGroup *cg = CacheGroupForName(m, q.qnamehash, &q.qname);
if (!mDNSOpaque16IsZero(response->h.id))
{
unicastQuestion = qptr;
@@ -9401,7 +9367,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
// have any record(s) of the same type that we should re-assert to rescue them
// (see note about "multi-homing and bridged networks" at the end of this function).
else if (m->rec.r.resrec.rrtype == rr->resrec.rrtype)
- if ((m->rec.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask) && m->timenow - rr->LastMCTime > mDNSPlatformOneSecond/2)
+ if ((m->rec.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask) && (mDNSu32)(m->timenow - rr->LastMCTime) > (mDNSu32)mDNSPlatformOneSecond/2)
{ rr->ImmedAnswer = mDNSInterfaceMark; m->NextScheduledResponse = m->timenow; }
}
}
@@ -9420,8 +9386,8 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
if (!AcceptableResponse) LogInfo("mDNSCoreReceiveResponse ignoring %s", CRDisplayString(m, &m->rec.r));
if (m->rrcache_size && AcceptableResponse)
{
- const mDNSu32 slot = HashSlot(m->rec.r.resrec.name);
- CacheGroup *cg = CacheGroupForRecord(m, slot, &m->rec.r.resrec);
+ const mDNSu32 slot = HashSlotFromNameHash(m->rec.r.resrec.namehash);
+ CacheGroup *cg = CacheGroupForRecord(m, &m->rec.r.resrec);
CacheRecord *rr = mDNSNULL;
if (McastNSEC3Records)
@@ -9447,7 +9413,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
if (AddToCFList)
delay = NonZeroTime(m->timenow + mDNSPlatformOneSecond);
else
- delay = CheckForSoonToExpireRecords(m, m->rec.r.resrec.name, m->rec.r.resrec.namehash, slot, mDNSNULL);
+ delay = CheckForSoonToExpireRecords(m, m->rec.r.resrec.name, m->rec.r.resrec.namehash, mDNSNULL);
// If unique, assume we may have to delay delivery of this 'add' event.
// Below, where we walk the CacheFlushRecords list, we either call CacheRecordDeferredAdd()
@@ -9513,8 +9479,8 @@ exit:
while (CacheFlushRecords != (CacheRecord*)1)
{
CacheRecord *r1 = CacheFlushRecords, *r2;
- const mDNSu32 slot = HashSlot(r1->resrec.name);
- const CacheGroup *cg = CacheGroupForRecord(m, slot, &r1->resrec);
+ const mDNSu32 slot = HashSlotFromNameHash(r1->resrec.namehash);
+ const CacheGroup *cg = CacheGroupForRecord(m, &r1->resrec);
CacheFlushRecords = CacheFlushRecords->NextInCFList;
r1->NextInCFList = mDNSNULL;
@@ -9664,7 +9630,7 @@ exit:
NSECRecords = mDNSNULL;
NSECCachePtr = mDNSNULL;
}
- r1->DelayDelivery = CheckForSoonToExpireRecords(m, r1->resrec.name, r1->resrec.namehash, slot, mDNSNULL);
+ r1->DelayDelivery = CheckForSoonToExpireRecords(m, r1->resrec.name, r1->resrec.namehash, mDNSNULL);
// If no longer delaying, deliver answer now, else schedule delivery for the appropriate time
if (!r1->DelayDelivery) CacheRecordDeferredAdd(m, r1);
else ScheduleNextCacheCheckTime(m, slot, r1->DelayDelivery);
@@ -10382,13 +10348,14 @@ mDNSlocal mDNSu32 mDNSGenerateOwnerOptForInterface(mDNS *const m, const mDNSInte
mDNSu8 *end = mDNSNULL;
mDNSu32 length = 0;
AuthRecord opt;
+ NetworkInterfaceInfo *intf;
mDNS_SetupResourceRecord(&opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
opt.resrec.rrclass = NormalMaxDNSMessageData;
opt.resrec.rdlength = sizeof(rdataOPT);
opt.resrec.rdestimate = sizeof(rdataOPT);
- NetworkInterfaceInfo *intf = FirstInterfaceForID(m, InterfaceID);
+ intf = FirstInterfaceForID(m, InterfaceID);
SetupOwnerOpt(m, intf, &opt.resrec.rdata->u.opt[0]);
LogSPS("Generated OPT record : %s", ARDisplayString(m, &opt));
@@ -10405,30 +10372,18 @@ mDNSlocal mDNSu32 mDNSGenerateOwnerOptForInterface(mDNS *const m, const mDNSInte
return length;
}
+// Note that this routine is called both for Sleep Proxy Registrations, and for Standard Dynamic
+// DNS registrations, but (currently) only has to handle the Sleep Proxy Registration reply case,
+// and should ignore Standard Dynamic DNS registration replies, because those are handled elsewhere.
+// Really, both should be unified and handled in one place.
mDNSlocal void mDNSCoreReceiveUpdateR(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *end, const mDNSAddr *srcaddr, const mDNSInterfaceID InterfaceID)
{
if (InterfaceID)
{
- 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);
- if (ptr && m->rec.r.resrec.RecordType != kDNSRecordTypePacketNegative && m->rec.r.resrec.rrtype == kDNSType_OPT)
- {
- const rdataOPT *o;
- const rdataOPT *const e = (const rdataOPT *)&m->rec.r.resrec.rdata->u.data[m->rec.r.resrec.rdlength];
- for (o = &m->rec.r.resrec.rdata->u.opt[0]; o < e; o++)
- if (o->opt == kDNSOpt_Lease)
- {
- updatelease = o->u.updatelease;
- LogSPS("Sleep Proxy granted lease time %4d seconds, updateid %d, InterfaceID %p", updatelease, mDNSVal16(msg->h.id), InterfaceID);
- }
- }
- m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
- }
+ mDNSu32 pktlease = 0, spsupdates = 0;
+ const mDNSBool gotlease = GetPktLease(m, msg, end, &pktlease);
+ const mDNSu32 updatelease = gotlease ? pktlease : 60 * 60; // If SPS fails to indicate lease time, assume one hour
+ if (gotlease) LogSPS("DNS Update response contains lease option granting %4d seconds, updateid %d, InterfaceID %p", updatelease, mDNSVal16(msg->h.id), InterfaceID);
if (m->CurrentRecord)
LogMsg("mDNSCoreReceiveUpdateR ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
@@ -10447,7 +10402,8 @@ mDNSlocal void mDNSCoreReceiveUpdateR(mDNS *const m, const DNSMessage *const msg
if (mDNSOpaque64IsZero(&rr->updateIntID))
rr->updateid = zeroID;
rr->expire = NonZeroTime(m->timenow + updatelease * mDNSPlatformOneSecond);
- LogSPS("Sleep Proxy %s record %5d 0x%x 0x%x (%d) %s", rr->WakeUp.HMAC.l[0] ? "transferred" : "registered", updatelease, rr->updateIntID.l[1], rr->updateIntID.l[0], mDNSVal16(rr->updateid), ARDisplayString(m,rr));
+ spsupdates++;
+ LogSPS("Sleep Proxy %s record %2d %5d 0x%x 0x%x (%d) %s", rr->WakeUp.HMAC.l[0] ? "transferred" : "registered", spsupdates, updatelease, rr->updateIntID.l[1], rr->updateIntID.l[0], mDNSVal16(rr->updateid), ARDisplayString(m,rr));
if (rr->WakeUp.HMAC.l[0])
{
rr->WakeUp.HMAC = zeroEthAddr; // Clear HMAC so that mDNS_Deregister_internal doesn't waste packets trying to wake this host
@@ -10460,22 +10416,26 @@ mDNSlocal void mDNSCoreReceiveUpdateR(mDNS *const m, const DNSMessage *const msg
if (m->CurrentRecord == rr) // If m->CurrentRecord was not advanced for us, do it now
m->CurrentRecord = rr->next;
}
-
- // Update the dynamic store with the IP Address and MAC address of the sleep proxy
- ifname = InterfaceNameForID(m, InterfaceID);
- mDNSPlatformMemCopy(&spsaddr, srcaddr, sizeof (mDNSAddr));
- mDNSPlatformStoreSPSMACAddr(&spsaddr, ifname);
-
- // Store the Owner OPT record for this interface.
- // Configd may use the OPT record if it detects a conflict with the BSP when the system wakes up
- DNSMessage optMsg;
- int length = 0;
- InitializeDNSMessage(&optMsg.h, zeroID, ResponseFlags);
- length = mDNSGenerateOwnerOptForInterface(m, InterfaceID, &optMsg);
- if (length != 0)
+ if (spsupdates) // Only do this dynamic store stuff if this was, in fact, a Sleep Proxy Update response
{
- length += sizeof(DNSMessageHeader);
- mDNSPlatformStoreOwnerOptRecord(ifname, &optMsg, length);
+ char *ifname;
+ mDNSAddr spsaddr;
+ DNSMessage optMsg;
+ int length;
+ // Update the dynamic store with the IP Address and MAC address of the sleep proxy
+ ifname = InterfaceNameForID(m, InterfaceID);
+ mDNSPlatformMemCopy(&spsaddr, srcaddr, sizeof (mDNSAddr));
+ mDNSPlatformStoreSPSMACAddr(&spsaddr, ifname);
+
+ // Store the Owner OPT record for this interface.
+ // Configd may use the OPT record if it detects a conflict with the BSP when the system wakes up
+ InitializeDNSMessage(&optMsg.h, zeroID, ResponseFlags);
+ length = mDNSGenerateOwnerOptForInterface(m, InterfaceID, &optMsg);
+ if (length != 0)
+ {
+ length += sizeof(DNSMessageHeader);
+ mDNSPlatformStoreOwnerOptRecord(ifname, &optMsg, length);
+ }
}
}
// If we were waiting to go to sleep, then this SPS registration or wide-area record deletion
@@ -10512,12 +10472,6 @@ mDNSexport void MakeNegativeCacheRecord(mDNS *const m, CacheRecord *const cr,
cr->CRActiveQuestion = mDNSNULL;
cr->UnansweredQueries = 0;
cr->LastUnansweredTime = 0;
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- cr->MPUnansweredQ = 0;
- cr->MPLastUnansweredQT = 0;
- cr->MPUnansweredKA = 0;
- cr->MPExpectingKA = mDNSfalse;
-#endif
cr->NextInCFList = mDNSNULL;
cr->nsec = mDNSNULL;
cr->soa = mDNSNULL;
@@ -10595,7 +10549,7 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNS
// 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) &&
+ if (!mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr) && dstaddr &&
mDNSAddressIsAllDNSLinkGroup(dstaddr))
{
m->RemoteSubnet++;
@@ -10624,8 +10578,8 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNS
{
static int msgCount = 0;
if (msgCount < 1000) {
- msgCount++;
int i = 0;
+ msgCount++;
LogInfo("Unknown DNS packet type %02X%02X from %#-15a:%-5d to %#-15a:%-5d length %d on %p (ignored)",
msg->h.flags.b[0], msg->h.flags.b[1], srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), (int)(end - pkt), InterfaceID);
while (i < (int)(end - pkt))
@@ -10658,6 +10612,11 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNS
#define SameQTarget(A,B) (((A)->Target.type == mDNSAddrType_None && (B)->Target.type == mDNSAddrType_None) || \
(mDNSSameAddress(& (A)->Target, & (B)->Target) && mDNSSameIPPort((A)->TargetPort, (B)->TargetPort)))
+// SameQuestionKind is true if *both* questions are either multicast or unicast
+// TargetQID is used for this determination.
+#define SameQuestionKind(A,B) ((mDNSOpaque16IsZero(A) && mDNSOpaque16IsZero(B)) || \
+ ((!mDNSOpaque16IsZero(A)) && (!mDNSOpaque16IsZero(B))))
+
// Note: We explicitly disallow making a public query be a duplicate of a private one. This is to avoid the
// circular deadlock where a client does a query for something like "dns-sd -Q _dns-query-tls._tcp.company.com SRV"
// and we have a key for company.com, so we try to locate the private query server for company.com, which necessarily entails
@@ -10701,8 +10660,9 @@ mDNSlocal DNSQuestion *FindDuplicateQuestion(const mDNS *const m, const DNSQuest
(q->DisallowPID == question->DisallowPID) && // Disallowing a PID should not affect a PID that is allowed
(q->BrowseThreshold == question->BrowseThreshold) && // browse thresholds must match
q->qnamehash == question->qnamehash &&
- (IsAWDLIncluded(q) == IsAWDLIncluded(question)) && // Inclusion of AWDL interface must match
- SameDomainName(&q->qname, &question->qname)) // and name
+ (IsAWDLIncluded(q) == IsAWDLIncluded(question)) && // Inclusion of AWDL interface must match
+ SameQuestionKind(q->TargetQID, question->TargetQID) && // mDNS or uDNS must match
+ SameDomainName(&q->qname, &question->qname)) // and name
return(q);
return(mDNSNULL);
}
@@ -11007,7 +10967,7 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
mDNSu32 timeout = 0;
mDNSBool DEQuery;
- question->validDNSServers = zeroOpaque64;
+ question->validDNSServers = zeroOpaque128;
DEQuery = DomainEnumQuery(&question->qname);
for (curr = m->DNSServers; curr; curr = curr->next)
{
@@ -11036,6 +10996,7 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
currcount = CountLabels(&curr->domain);
if ((!curr->cellIntf || (!DEQuery && !(question->flags & kDNSServiceFlagsDenyCellular))) &&
+ (!curr->isExpensive || !(question->flags & kDNSServiceFlagsDenyExpensive)) &&
DNSServerMatch(curr, question->InterfaceID, question->ServiceID))
{
bettermatch = BetterMatchForName(&question->qname, namecount, &curr->domain, currcount, bestmatchlen);
@@ -11050,7 +11011,7 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
if (bettermatch)
{
debugf("SetValidDNSServers: Resetting all the bits");
- question->validDNSServers = zeroOpaque64;
+ question->validDNSServers = zeroOpaque128;
timeout = 0;
}
debugf("SetValidDNSServers: question %##s Setting the bit for DNS server Address %#a (Domain %##s), Scoped:%d index %d,"
@@ -11059,15 +11020,15 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
timeout += curr->timeout;
if (DEQuery)
debugf("DomainEnumQuery: Question %##s, DNSServer %#a, cell %d", question->qname.c, &curr->addr, curr->cellIntf);
- bit_set_opaque64(question->validDNSServers, index);
+ bit_set_opaque128(question->validDNSServers, index);
}
}
index++;
}
question->noServerResponse = 0;
- debugf("SetValidDNSServers: ValidDNSServer bits 0x%x%x for question %p %##s (%s)",
- question->validDNSServers.l[1], question->validDNSServers.l[0], question, question->qname.c, DNSTypeName(question->qtype));
+ debugf("SetValidDNSServers: ValidDNSServer bits 0x%x%x%x%x for question %p %##s (%s)",
+ question->validDNSServers.l[3], question->validDNSServers.l[2], question->validDNSServers.l[1], question->validDNSServers.l[0], question, question->qname.c, DNSTypeName(question->qtype));
// If there are no matching resolvers, then use the default timeout value.
// For ProxyQuestion, shorten the timeout so that dig does not timeout on us in case of no response.
return ((question->ProxyQuestion || question->ValidatingResponse) ? DEFAULT_UDNSSEC_TIMEOUT : timeout ? timeout : DEFAULT_UDNS_TIMEOUT);
@@ -11075,7 +11036,7 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
// Get the Best server that matches a name. If you find penalized servers, look for the one
// that will come out of the penalty box soon
-mDNSlocal DNSServer *GetBestServer(mDNS *m, const domainname *name, mDNSInterfaceID InterfaceID, mDNSs32 ServiceID, mDNSOpaque64 validBits,
+mDNSlocal DNSServer *GetBestServer(mDNS *m, const domainname *name, mDNSInterfaceID InterfaceID, mDNSs32 ServiceID, mDNSOpaque128 validBits,
int *selected, mDNSBool nameMatch)
{
DNSServer *curmatch = mDNSNULL;
@@ -11154,7 +11115,7 @@ mDNSlocal DNSServer *GetServerForName(mDNS *m, const domainname *name, mDNSInter
{
DNSServer *curmatch = mDNSNULL;
char *ifname = mDNSNULL; // for logging purposes only
- mDNSOpaque64 allValid;
+ mDNSOpaque128 allValid;
if ((InterfaceID == mDNSInterface_Unicast) || (InterfaceID == mDNSInterface_LocalOnly))
InterfaceID = mDNSNULL;
@@ -11162,7 +11123,7 @@ mDNSlocal DNSServer *GetServerForName(mDNS *m, const domainname *name, mDNSInter
if (InterfaceID) ifname = InterfaceNameForID(m, InterfaceID);
// By passing in all ones, we make sure that every DNS server is considered
- allValid.l[0] = allValid.l[1] = 0xFFFFFFFF;
+ allValid.l[0] = allValid.l[1] = allValid.l[2] = allValid.l[3] = 0xFFFFFFFF;
curmatch = GetBestServer(m, name, InterfaceID, ServiceID, allValid, mDNSNULL, mDNStrue);
@@ -11191,11 +11152,11 @@ mDNSexport DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question)
if (InterfaceID)
ifname = InterfaceNameForID(m, InterfaceID);
- if (!mDNSOpaque64IsZero(&question->validDNSServers))
+ if (!mDNSOpaque128IsZero(&question->validDNSServers))
{
curmatch = GetBestServer(m, name, InterfaceID, question->ServiceID, question->validDNSServers, &currindex, mDNSfalse);
if (currindex != -1)
- bit_clr_opaque64(question->validDNSServers, currindex);
+ bit_clr_opaque128(question->validDNSServers, currindex);
}
if (curmatch != mDNSNULL)
@@ -11289,6 +11250,13 @@ mDNSlocal mDNSBool ShouldSuppressUnicastQuery(mDNS *const m, DNSQuestion *q, DNS
DNSTypeName(q->qtype), d->domain.c, &d->addr, mDNSVal16(d->port));
return mDNSfalse;
}
+#if USE_DNS64
+ if (DNS64IsQueryingARecord(q->dns64.state))
+ {
+ LogInfo("ShouldSuppressUnicastQuery: DNS64 query not suppressed for %##s, qtype %s", q->qname.c, DNSTypeName(q->qtype));
+ return mDNSfalse;
+ }
+#endif
LogInfo("ShouldSuppressUnicastQuery: Query suppressed for %##s, qtype %s, since DNS Configuration does not allow (req_A is %s and req_AAAA is %s)",
q->qname.c, DNSTypeName(q->qtype), d->req_A ? "true" : "false", d->req_AAAA ? "true" : "false");
@@ -11384,11 +11352,9 @@ mDNSlocal mDNSBool ShouldSuppressQuery(mDNS *const m, DNSQuestion *q)
mDNSlocal void CacheRecordRmvEventsForCurrentQuestion(mDNS *const m, DNSQuestion *q)
{
CacheRecord *rr;
- mDNSu32 slot;
CacheGroup *cg;
- slot = HashSlot(&q->qname);
- cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ cg = CacheGroupForName(m, q->qnamehash, &q->qname);
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
{
// Don't deliver RMV events for negative records
@@ -11445,7 +11411,6 @@ mDNSlocal mDNSBool IsQuestionNew(mDNS *const m, DNSQuestion *question)
mDNSlocal mDNSBool LocalRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q)
{
AuthRecord *rr;
- mDNSu32 slot;
AuthGroup *ag;
if (m->CurrentQuestion)
@@ -11458,8 +11423,7 @@ mDNSlocal mDNSBool LocalRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q
return mDNStrue;
}
m->CurrentQuestion = q;
- slot = AuthHashSlot(&q->qname);
- ag = AuthGroupForName(&m->rrauth, slot, q->qnamehash, &q->qname);
+ ag = AuthGroupForName(&m->rrauth, q->qnamehash, &q->qname);
if (ag)
{
for (rr = ag->members; rr; rr=rr->next)
@@ -11485,7 +11449,7 @@ mDNSlocal mDNSBool LocalRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q
// Returns false if the question got deleted while delivering the RMV events
// The caller should handle the case
-mDNSlocal mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q)
+mDNSexport mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q)
{
if (m->CurrentQuestion)
LogMsg("CacheRecordRmvEventsForQuestion: ERROR m->CurrentQuestion already set: %##s (%s)",
@@ -11684,33 +11648,29 @@ mDNSlocal void InitDNSConfig(mDNS *const m, DNSQuestion *const question)
{
// First reset all DNS Configuration
question->qDNSServer = mDNSNULL;
- question->validDNSServers = zeroOpaque64;
+ question->validDNSServers = zeroOpaque128;
question->triedAllServersOnce = 0;
question->noServerResponse = 0;
- question->StopTime = 0;
-#if TARGET_OS_EMBEDDED
+ question->StopTime = (question->TimeoutQuestion) ? question->StopTime : 0;
+#if AWD_METRICS
mDNSPlatformMemZero(&question->metrics, sizeof(question->metrics));
#endif
- // Need not initialize the DNS Configuration for Local Only OR P2P Questions
- if (LocalOnlyOrP2PInterface(question->InterfaceID))
+ // Need not initialize the DNS Configuration for Local Only OR P2P Questions when timeout not specified
+ if (LocalOnlyOrP2PInterface(question->InterfaceID) && !question->TimeoutQuestion)
return;
// Proceed to initialize DNS Configuration (some are set in SetValidDNSServers())
if (!mDNSOpaque16IsZero(question->TargetQID))
{
mDNSu32 timeout = SetValidDNSServers(m, question);
- // We set the timeout whenever mDNS_StartQuery_internal is called. This means if we have
- // a networking change/search domain change that calls this function again we keep
- // reinitializing the timeout value which means it may never timeout. If this becomes
- // a common case in the future, we can easily fix this by adding extra state that
- // indicates that we have already set the StopTime.
- //
- // Note that we set the timeout for all questions. If this turns out to be a duplicate,
+ // We set the timeout value the first time mDNS_StartQuery_internal is called for a question.
+ // So if a question is restarted when a network change occurs, the StopTime is not reset.
+ // Note that we set the timeout for all questions. If this turns out to be a duplicate,
// it gets a full timeout value even if the original question times out earlier.
- if (question->TimeoutQuestion)
+ if (question->TimeoutQuestion && !question->StopTime)
{
question->StopTime = NonZeroTime(m->timenow + timeout * mDNSPlatformOneSecond);
- LogInfo("InitDNSConfig: Setting StopTime on question %p %##s (%s)", question, question->qname.c, DNSTypeName(question->qtype));
+ LogInfo("InitDNSConfig: Setting StopTime on the uDNS question %p %##s (%s)", question, question->qname.c, DNSTypeName(question->qtype));
}
question->qDNSServer = GetServerForQuestion(m, question);
@@ -11719,17 +11679,22 @@ mDNSlocal void InitDNSConfig(mDNS *const m, DNSQuestion *const question)
question->qDNSServer ? &question->qDNSServer->addr : mDNSNULL,
mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zeroIPPort));
}
- else
+ else if (question->TimeoutQuestion && !question->StopTime)
{
- if (question->TimeoutQuestion)
- question->StopTime = NonZeroTime(m->timenow + GetTimeoutForMcastQuestion(m, question) * mDNSPlatformOneSecond);
+ // If the question is to be timed out and its a multicast, local-only or P2P case,
+ // then set it's stop time.
+ mDNSu32 timeout = LocalOnlyOrP2PInterface(question->InterfaceID) ?
+ DEFAULT_LO_OR_P2P_TIMEOUT : GetTimeoutForMcastQuestion(m, question);
+ question->StopTime = NonZeroTime(m->timenow + timeout * mDNSPlatformOneSecond);
+ LogInfo("InitDNSConfig: Setting StopTime on question %p %##s (%s)", question, question->qname.c, DNSTypeName(question->qtype));
}
// Set StopTime here since it is a part of DNS Configuration
if (question->StopTime)
SetNextQueryStopTime(m, question);
- // SetNextQueryTime() need not be initialized for LocalOnly OR P2P Questions since those questions
- // will never be transmitted on the wire. Hence we call SetNextQueryTime() here.
- SetNextQueryTime(m,question);
+ // Don't call SetNextQueryTime() if a LocalOnly OR P2P Question since those questions
+ // will never be transmitted on the wire.
+ if (!(LocalOnlyOrP2PInterface(question->InterfaceID)))
+ SetNextQueryTime(m,question);
}
// InitCommonState() is called by mDNS_StartQuery_internal() to initialize the common(uDNS/mDNS) internal
@@ -11755,7 +11720,7 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
// turned ON which can allocate memory e.g., base64 encoding, in the case of DNSSEC.
question->ThisQInterval = InitialQuestionInterval; // MUST be > zero for an active question
question->qnamehash = DomainNameHashValue(&question->qname);
- question->DelayAnswering = CheckForSoonToExpireRecords(m, &question->qname, question->qnamehash, HashSlot(&question->qname), &purge);
+ question->DelayAnswering = CheckForSoonToExpireRecords(m, &question->qname, question->qnamehash, &purge);
question->LastQTime = m->timenow;
question->ExpectUnicastResp = 0;
question->LastAnswerPktNum = m->PktNum;
@@ -11792,7 +11757,7 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
if (!(question->flags & kDNSServiceFlagsServiceIndex))
{
#if APPLE_OSX_mDNSResponder
- mDNSPlatformGetDNSRoutePolicy(m, question, &isBlocked);
+ mDNSPlatformGetDNSRoutePolicy(question, &isBlocked);
#else
question->ServiceID = -1;
#endif
@@ -11897,10 +11862,12 @@ mDNSlocal void InitLLQState(DNSQuestion *const question)
question->id = zeroOpaque64;
}
+#ifdef DNS_PUSH_ENABLED
mDNSlocal void InitDNSPNState(DNSQuestion *const question)
{
question->dnsPushState = DNSPUSH_INIT;
}
+#endif // DNS_PUSH_ENABLED
// InitDNSSECProxyState() is called by mDNS_StartQuery_internal() to initialize
// DNSSEC & DNS Proxy fields of the DNS Question.
@@ -11941,6 +11908,16 @@ mDNSlocal void FinalizeUnicastQuestion(mDNS *const m, DNSQuestion *question, mDN
if (question->DuplicateOf)
{
question->validDNSServers = question->DuplicateOf->validDNSServers;
+ // If current(dup) question has DNS Server assigned but the original question has no DNS Server assigned to it,
+ // then we log a line as it could indicate an issue
+ if (question->DuplicateOf->qDNSServer == mDNSNULL)
+ {
+ if (question->qDNSServer)
+ LogInfo("FinalizeUnicastQuestion: Current(dup) question %p has DNSServer(%#a:%d) but original question(%p) has no DNS Server! %##s (%s)",
+ question, question->qDNSServer ? &question->qDNSServer->addr : mDNSNULL,
+ mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zeroIPPort),
+ question->DuplicateOf, question->qname.c, DNSTypeName(question->qtype));
+ }
question->qDNSServer = question->DuplicateOf->qDNSServer;
LogInfo("FinalizeUnicastQuestion: Duplicate question %p (%p) %##s (%s), DNS Server %#a:%d",
question, question->DuplicateOf, question->qname.c, DNSTypeName(question->qtype),
@@ -12031,7 +12008,9 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
purge = InitCommonState(m, question);
InitWABState(question);
InitLLQState(question);
+#ifdef DNS_PUSH_ENABLED
InitDNSPNState(question);
+#endif // DNS_PUSH_ENABLED
InitDNSSECProxyState(m, question);
// FindDuplicateQuestion should be called last after all the intialization
@@ -12108,8 +12087,7 @@ mDNSexport void CancelGetZoneData(mDNS *const m, ZoneData *nta)
mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const question)
{
- const mDNSu32 slot = HashSlot(&question->qname);
- CacheGroup *cg = CacheGroupForName(m, slot, question->qnamehash, &question->qname);
+ CacheGroup *cg = CacheGroupForName(m, question->qnamehash, &question->qname);
CacheRecord *rr;
DNSQuestion **qp = &m->Questions;
@@ -12139,24 +12117,16 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
}
#endif // BONJOUR_ON_DEMAND
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
if (Question_uDNS(question) && !question->metrics.answered && (question->metrics.querySendCount > 0))
{
const domainname * queryName;
mDNSBool isForCell;
mDNSu32 durationMs;
- queryName = question->metrics.originalQName ? question->metrics.originalQName : &question->qname;
- isForCell = (question->qDNSServer && question->qDNSServer->cellIntf);
-
- if (question->metrics.querySendCount > 0)
- {
- durationMs = ((m->timenow - question->metrics.firstQueryTime) * 1000) / mDNSPlatformOneSecond;
- }
- else
- {
- durationMs = 0;
- }
+ queryName = question->metrics.originalQName ? question->metrics.originalQName : &question->qname;
+ isForCell = (question->qDNSServer && question->qDNSServer->cellIntf);
+ durationMs = ((m->timenow - question->metrics.firstQueryTime) * 1000) / mDNSPlatformOneSecond;
MetricsUpdateUDNSQueryStats(queryName, question->qtype, mDNSNULL, question->metrics.querySendCount, durationMs, isForCell);
}
#endif
@@ -12279,6 +12249,7 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
question->tcp = mDNSNULL;
}
}
+#ifdef DNS_PUSH_ENABLED
else if (question->dnsPushState == DNSPUSH_ESTABLISHED)
{
if (question->tcp)
@@ -12288,6 +12259,7 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
question->tcp = mDNSNULL;
}
}
+#endif // DNS_PUSH_ENABLED
#if APPLE_OSX_mDNSResponder
UpdateAutoTunnelDomainStatuses(m);
#endif
@@ -12306,7 +12278,7 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
FreeAnonInfo(question->AnonInfo);
question->AnonInfo = mDNSNULL;
}
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
if (question->metrics.originalQName)
{
mDNSPlatformMemFree(question->metrics.originalQName);
@@ -12314,6 +12286,10 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
}
#endif
+#if USE_DNS64
+ DNS64ResetState(question);
+#endif
+
return(mStatus_NoError);
}
@@ -12352,8 +12328,7 @@ mDNSexport mStatus mDNS_StopQueryWithRemoves(mDNS *const m, DNSQuestion *const q
if (status == mStatus_NoError && !qq)
{
const CacheRecord *rr;
- const mDNSu32 slot = HashSlot(&question->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, question->qnamehash, &question->qname);
+ CacheGroup *const cg = CacheGroupForName(m, question->qnamehash, &question->qname);
LogInfo("Generating terminal removes for %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
if (rr->resrec.RecordType != kDNSRecordTypePacketNegative && SameNameRecordAnswersQuestion(&rr->resrec, question))
@@ -12585,6 +12560,8 @@ mDNSlocal NetworkInterfaceInfo *FindFirstAdvertisedInterface(mDNS *const m)
return(intf);
}
+// The parameter "set" here refers to the set of AuthRecords used to advertise this interface.
+// (It's a set of records, not a set of interfaces.)
mDNSlocal void AdvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
{
char buffer[MAX_REVERSE_MAPPING_NAME];
@@ -12599,6 +12576,8 @@ mDNSlocal void AdvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
primary = FindFirstAdvertisedInterface(m);
if (!primary) primary = set; // If no existing advertised interface, this new NetworkInterfaceInfo becomes our new primary
+ // We should never have primary be NULL, because even if there is
+ // no other interface yet, we should always find ourself in the list.
// 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.
@@ -12608,9 +12587,9 @@ mDNSlocal void AdvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
LogInfo("AdvertiseInterface: Marking address record as kDNSRecordTypeKnownUnique for %s", set->ifname);
// Send dynamic update for non-linklocal IPv4 Addresses
- mDNS_SetupResourceRecord(&set->RR_A, mDNSNULL, set->InterfaceID, kDNSType_A, kHostNameTTL, recordType, AuthRecordAny, mDNS_HostNameCallback, set);
- mDNS_SetupResourceRecord(&set->RR_PTR, mDNSNULL, set->InterfaceID, kDNSType_PTR, kHostNameTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
- mDNS_SetupResourceRecord(&set->RR_HINFO, mDNSNULL, set->InterfaceID, kDNSType_HINFO, kHostNameTTL, kDNSRecordTypeUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
+ mDNS_SetupResourceRecord(&set->RR_A, mDNSNULL, set->InterfaceID, kDNSType_A, kHostNameTTL, recordType, AuthRecordAny, mDNS_HostNameCallback, set);
+ mDNS_SetupResourceRecord(&set->RR_PTR, mDNSNULL, set->InterfaceID, kDNSType_PTR, kHostNameTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
+ mDNS_SetupResourceRecord(&set->RR_HINFO, mDNSNULL, set->InterfaceID, kDNSType_HINFO, kHostNameTTL, kDNSRecordTypeUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
#if ANSWER_REMOTE_HOSTNAME_QUERIES
set->RR_A.AllowRemoteQuery = mDNStrue;
@@ -12907,7 +12886,7 @@ mDNSexport void mDNS_DeactivateNetWake_internal(mDNS *const m, NetworkInterfaceI
}
}
-mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping)
+mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed activationSpeed)
{
AuthRecord *rr;
mDNSBool FirstOfType = mDNStrue;
@@ -12978,32 +12957,56 @@ mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *s
// We don't want to do a probe, and then see a stale echo of an announcement we ourselves sent,
// and think it's a conflicting answer to our probe.
// In the case of a flapping interface, we pause for five seconds, and reduce the announcement count to one packet.
- const mDNSs32 probedelay = flapping ? mDNSPlatformOneSecond * 5 : mDNSPlatformOneSecond / 2;
- const mDNSu8 numannounce = flapping ? (mDNSu8)1 : InitialAnnounceCount;
+ mDNSs32 probedelay;
+ mDNSu8 numannounce;
+ switch (activationSpeed)
+ {
+ case FastActivation:
+ probedelay = (mDNSs32)0;
+ numannounce = InitialAnnounceCount;
+ LogMsg("mDNS_RegisterInterface: Using fast activation for DirectLink interface %s (%#a)", set->ifname, &set->ip);
+ break;
- // Use a small amount of randomness:
- // In the case of a network administrator turning on an Ethernet hub so that all the
- // connected machines establish link at exactly the same time, we don't want them all
- // to go and hit the network with identical queries at exactly the same moment.
- // We set a random delay of up to InitialQuestionInterval (1/3 second).
- // We must *never* set m->SuppressSending to more than that (or set it repeatedly in a way
- // that causes mDNSResponder to remain in a prolonged state of SuppressSending, because
- // suppressing packet sending for more than about 1/3 second can cause protocol correctness
- // to start to break down (e.g. we don't answer probes fast enough, and get name conflicts).
- // See <rdar://problem/4073853> mDNS: m->SuppressSending set too enthusiastically
- if (!m->SuppressSending) m->SuppressSending = m->timenow + (mDNSs32)mDNSRandom((mDNSu32)InitialQuestionInterval);
+ case SlowActivation:
+ probedelay = mDNSPlatformOneSecond * 5;
+ numannounce = (mDNSu8)1;
+ LogMsg("mDNS_RegisterInterface: Frequent transitions for interface %s (%#a), doing slow activation", set->ifname, &set->ip);
+ m->mDNSStats.InterfaceUpFlap++;
+ break;
- if (flapping)
- {
- LogMsg("mDNS_RegisterInterface: Frequent transitions for interface %s (%#a)", set->ifname, &set->ip);
- m->mDNSStats.InterfaceUpFlap++;
+ case NormalActivation:
+ default:
+ probedelay = mDNSPlatformOneSecond / 2;
+ numannounce = InitialAnnounceCount;
+ break;
}
LogInfo("mDNS_RegisterInterface: %s (%#a) probedelay %d", set->ifname, &set->ip, probedelay);
- if (m->SuppressProbes == 0 ||
- m->SuppressProbes - NonZeroTime(m->timenow + probedelay) < 0)
- m->SuppressProbes = NonZeroTime(m->timenow + probedelay);
+ // No probe or sending suppression on DirectLink type interfaces.
+ if (activationSpeed == FastActivation)
+ {
+ m->SuppressSending = 0;
+ m->SuppressProbes = 0;
+ }
+ else
+ {
+ // Use a small amount of randomness:
+ // In the case of a network administrator turning on an Ethernet hub so that all the
+ // connected machines establish link at exactly the same time, we don't want them all
+ // to go and hit the network with identical queries at exactly the same moment.
+ // We set a random delay of up to InitialQuestionInterval (1/3 second).
+ // We must *never* set m->SuppressSending to more than that (or set it repeatedly in a way
+ // that causes mDNSResponder to remain in a prolonged state of SuppressSending, because
+ // suppressing packet sending for more than about 1/3 second can cause protocol correctness
+ // to start to break down (e.g. we don't answer probes fast enough, and get name conflicts).
+ // See <rdar://problem/4073853> mDNS: m->SuppressSending set too enthusiastically
+ if (!m->SuppressSending) m->SuppressSending = m->timenow + (mDNSs32)mDNSRandom((mDNSu32)InitialQuestionInterval);
+
+ if (m->SuppressProbes == 0 ||
+ m->SuppressProbes - NonZeroTime(m->timenow + probedelay) < 0)
+ m->SuppressProbes = NonZeroTime(m->timenow + probedelay);
+ }
// Include OWNER option in packets for 60 seconds after connecting to the network. Setting
// it here also handles the wake up case as the network link comes UP after waking causing
@@ -13020,10 +13023,10 @@ mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *s
if (!q->InterfaceID || q->InterfaceID == set->InterfaceID) // If non-specific Q, or Q on this specific interface,
{ // then reactivate this question
// If flapping, delay between first and second queries is nine seconds instead of one second
- mDNSBool dodelay = flapping && (q->FlappingInterface1 == set->InterfaceID || q->FlappingInterface2 == set->InterfaceID);
+ mDNSBool dodelay = (activationSpeed == SlowActivation) && (q->FlappingInterface1 == set->InterfaceID || q->FlappingInterface2 == set->InterfaceID);
mDNSs32 initial = dodelay ? InitialQuestionInterval * QuestionIntervalStep2 : InitialQuestionInterval;
- mDNSs32 qdelay = dodelay ? mDNSPlatformOneSecond * 5 : 0;
- if (dodelay) LogInfo("No cache records expired for %##s (%s); okay to delay questions a little", q->qname.c, DNSTypeName(q->qtype));
+ mDNSs32 qdelay = dodelay ? kDefaultQueryDelayTimeForFlappingInterface : 0;
+ if (dodelay) LogInfo("No cache records expired for %##s (%s); delaying questions by %d seconds", q->qname.c, DNSTypeName(q->qtype), qdelay);
if (!q->ThisQInterval || q->ThisQInterval > initial)
{
@@ -13066,7 +13069,7 @@ mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *s
// Note: mDNS_DeregisterInterface 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.
-mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping)
+mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed activationSpeed)
{
NetworkInterfaceInfo **p = &m->HostInterfaces;
mDNSBool revalidate = mDNSfalse;
@@ -13126,7 +13129,7 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
m->mDNSStats.InterfaceDown++;
- if (set->McastTxRx && flapping)
+ if (set->McastTxRx && (activationSpeed == SlowActivation))
{
LogMsg("mDNS_DeregisterInterface: Frequent transitions for interface %s (%#a)", set->ifname, &set->ip);
m->mDNSStats.InterfaceDownFlap++;
@@ -13152,9 +13155,10 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
{
// If this interface is deemed flapping,
// postpone deleting the cache records in case the interface comes back again
- if (set->McastTxRx && flapping)
+ if (set->McastTxRx && (activationSpeed == SlowActivation))
{
- // For a flapping interface we want these record to go away after 30 seconds
+ // For a flapping interface we want these records to go away after
+ // kDefaultReconfirmTimeForFlappingInterface seconds if they are not reconfirmed.
mDNS_Reconfirm_internal(m, rr, kDefaultReconfirmTimeForFlappingInterface);
// We set UnansweredQueries = MaxUnansweredQueries so we don't waste time doing any queries for them --
// if the interface does come back, any relevant questions will be reactivated anyway
@@ -13314,10 +13318,7 @@ mDNSlocal void NSSCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
}
-// Derive AuthRecType from the coreFlag* values.
-// Note, this is not using the external flags values, kDNSServiceFlags*, defined in dns_sd.h.
-// It should be changed to do so once the use of coreFlag* is completely replaced with
-// the use the kDNSServiceFlags* definitions within mDNSResponder.
+// Derive AuthRecType from the kDNSServiceFlags* values.
mDNSlocal AuthRecType setAuthRecType(mDNSInterfaceID InterfaceID, mDNSu32 flags)
{
AuthRecType artype;
@@ -13326,12 +13327,12 @@ mDNSlocal AuthRecType setAuthRecType(mDNSInterfaceID InterfaceID, mDNSu32 flags)
artype = AuthRecordLocalOnly;
else if (InterfaceID == mDNSInterface_P2P || InterfaceID == mDNSInterface_BLE)
artype = AuthRecordP2P;
- else if ((InterfaceID == mDNSInterface_Any) && (flags & coreFlagIncludeP2P)
- && (flags & coreFlagIncludeAWDL))
+ else if ((InterfaceID == mDNSInterface_Any) && (flags & kDNSServiceFlagsIncludeP2P)
+ && (flags & kDNSServiceFlagsIncludeAWDL))
artype = AuthRecordAnyIncludeAWDLandP2P;
- else if ((InterfaceID == mDNSInterface_Any) && (flags & coreFlagIncludeP2P))
+ else if ((InterfaceID == mDNSInterface_Any) && (flags & kDNSServiceFlagsIncludeP2P))
artype = AuthRecordAnyIncludeP2P;
- else if ((InterfaceID == mDNSInterface_Any) && (flags & coreFlagIncludeAWDL))
+ else if ((InterfaceID == mDNSInterface_Any) && (flags & kDNSServiceFlagsIncludeAWDL))
artype = AuthRecordAnyIncludeAWDL;
else
artype = AuthRecordAny;
@@ -13370,7 +13371,7 @@ mDNSexport mStatus mDNS_RegisterService(mDNS *const m, ServiceRecordSet *sr,
mDNSu32 i;
mDNSu32 hostTTL;
AuthRecType artype;
- mDNSu8 recordType = (flags & coreFlagKnownUnique) ? kDNSRecordTypeKnownUnique : kDNSRecordTypeUnique;
+ mDNSu8 recordType = (flags & kDNSServiceFlagsKnownUnique) ? kDNSRecordTypeKnownUnique : kDNSRecordTypeUnique;
sr->ServiceCallback = Callback;
sr->ServiceContext = Context;
@@ -13388,7 +13389,7 @@ mDNSexport mStatus mDNS_RegisterService(mDNS *const m, ServiceRecordSet *sr,
mDNS_SetupResourceRecord(&sr->RR_ADV, mDNSNULL, InterfaceID, kDNSType_PTR, kStandardTTL, kDNSRecordTypeAdvisory, artype, ServiceCallback, sr);
mDNS_SetupResourceRecord(&sr->RR_PTR, mDNSNULL, InterfaceID, kDNSType_PTR, kStandardTTL, kDNSRecordTypeShared, artype, ServiceCallback, sr);
- if (flags & coreFlagWakeOnly)
+ if (flags & kDNSServiceFlagsWakeOnlyService)
{
sr->RR_PTR.AuthFlags = AuthFlagsWakeOnly;
}
@@ -13399,7 +13400,7 @@ mDNSexport mStatus mDNS_RegisterService(mDNS *const m, ServiceRecordSet *sr,
hostTTL = kHostNameTTL;
mDNS_SetupResourceRecord(&sr->RR_SRV, mDNSNULL, InterfaceID, kDNSType_SRV, hostTTL, recordType, artype, ServiceCallback, sr);
- mDNS_SetupResourceRecord(&sr->RR_TXT, mDNSNULL, InterfaceID, kDNSType_TXT, kStandardTTL, kDNSRecordTypeUnique, artype, ServiceCallback, sr);
+ mDNS_SetupResourceRecord(&sr->RR_TXT, mDNSNULL, InterfaceID, kDNSType_TXT, kStandardTTL, recordType, artype, ServiceCallback, sr);
// If port number is zero, that means the client is really trying to do a RegisterNoSuchService
if (mDNSIPPortIsZero(port))
@@ -13841,7 +13842,7 @@ mDNSlocal void mDNSCoreReceiveRawARP(mDNS *const m, const ARP_EthIP *const arp,
}
else if (msg == msg3)
{
- mDNSPlatformSetLocalAddressCacheEntry(m, &rr->AddressProxy, &rr->WakeUp.IMAC, InterfaceID);
+ mDNSPlatformSetLocalAddressCacheEntry(&rr->AddressProxy, &rr->WakeUp.IMAC, InterfaceID);
}
else if (msg == msg4)
{
@@ -13947,7 +13948,7 @@ mDNSlocal void mDNSCoreReceiveRawND(mDNS *const m, const mDNSEthAddr *const sha,
LogSPS("Reached maximum number of restarts for probing - %s", ARDisplayString(m,rr));
}
else if (msg == msg3)
- mDNSPlatformSetLocalAddressCacheEntry(m, &rr->AddressProxy, &rr->WakeUp.IMAC, InterfaceID);
+ mDNSPlatformSetLocalAddressCacheEntry(&rr->AddressProxy, &rr->WakeUp.IMAC, InterfaceID);
else if (msg == msg4)
SendNDP(m, NDP_Adv, NDP_Solicited, rr, &ndp->target, mDNSNULL, spa, sha);
else if (msg == msg5)
@@ -14286,7 +14287,7 @@ mDNSexport void mDNSCoreBeSleepProxyServer_internal(mDNS *const m, mDNSu8 sps, m
{
if (!m->SPSSocket)
{
- m->SPSSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
+ m->SPSSocket = mDNSPlatformUDPSocket(zeroIPPort);
if (!m->SPSSocket) { LogMsg("mDNSCoreBeSleepProxyServer: Failed to allocate SPSSocket"); goto fail; }
}
#ifndef SPC_DISABLED
@@ -14328,9 +14329,9 @@ mDNSexport void mDNS_GrowCache(mDNS *const m, CacheEntity *storage, mDNSu32 numr
mDNS_Unlock(m);
}
-mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
- CacheEntity *rrcachestorage, mDNSu32 rrcachesize,
- mDNSBool AdvertiseLocalAddresses, mDNSCallback *Callback, void *Context)
+mDNSlocal mStatus mDNS_InitStorage(mDNS *const m, mDNS_PlatformSupport *const p,
+ CacheEntity *rrcachestorage, mDNSu32 rrcachesize,
+ mDNSBool AdvertiseLocalAddresses, mDNSCallback *Callback, void *Context)
{
mDNSu32 slot;
mDNSs32 timenow;
@@ -14370,14 +14371,14 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
m->timenow_last = timenow;
m->NextScheduledEvent = timenow;
m->SuppressSending = timenow;
- m->NextCacheCheck = timenow + 0x78000000;
- m->NextScheduledQuery = timenow + 0x78000000;
- m->NextScheduledProbe = timenow + 0x78000000;
- m->NextScheduledResponse = timenow + 0x78000000;
- m->NextScheduledNATOp = timenow + 0x78000000;
- m->NextScheduledSPS = timenow + 0x78000000;
- m->NextScheduledKA = timenow + 0x78000000;
- m->NextScheduledStopTime = timenow + 0x78000000;
+ m->NextCacheCheck = timenow + FutureTime;
+ m->NextScheduledQuery = timenow + FutureTime;
+ m->NextScheduledProbe = timenow + FutureTime;
+ m->NextScheduledResponse = timenow + FutureTime;
+ m->NextScheduledNATOp = timenow + FutureTime;
+ m->NextScheduledSPS = timenow + FutureTime;
+ m->NextScheduledKA = timenow + FutureTime;
+ m->NextScheduledStopTime = timenow + FutureTime;
m->NextBLEServiceTime = 0; // zero indicates inactive
#if BONJOUR_ON_DEMAND
@@ -14399,9 +14400,6 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
m->SleepLimit = 0;
#if APPLE_OSX_mDNSResponder
- m->StatStartTime = mDNSPlatformUTC();
- m->NextStatLogTime = m->StatStartTime + kDefaultNextStatsticsLogTime;
- m->ActiveStatTime = 0;
m->UnicastPacketsSent = 0;
m->MulticastPacketsSent = 0;
m->RemoteSubnet = 0;
@@ -14424,7 +14422,7 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
for (slot = 0; slot < CACHE_HASH_SLOTS; slot++)
{
m->rrcache_hash[slot] = mDNSNULL;
- m->rrcache_nextcheck[slot] = timenow + 0x78000000;;
+ m->rrcache_nextcheck[slot] = timenow + FutureTime;;
}
mDNS_GrowCache_internal(m, rrcachestorage, rrcachesize);
@@ -14450,8 +14448,8 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
m->SuppressProbes = 0;
#ifndef UNICAST_DISABLED
- m->NextuDNSEvent = timenow + 0x78000000;
- m->NextSRVUpdate = timenow + 0x78000000;
+ m->NextuDNSEvent = timenow + FutureTime;
+ m->NextSRVUpdate = timenow + FutureTime;
m->DNSServers = mDNSNULL;
@@ -14482,7 +14480,7 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
m->NATTraversals = mDNSNULL;
m->CurrentNATTraversal = mDNSNULL;
m->retryIntervalGetAddr = 0; // delta between time sent and retry
- m->retryGetAddr = timenow + 0x78000000; // absolute time when we retry
+ m->retryGetAddr = timenow + FutureTime; // absolute time when we retry
m->ExtAddress = zerov4Addr;
m->PCPNonce[0] = mDNSRandom(-1);
m->PCPNonce[1] = mDNSRandom(-1);
@@ -14531,6 +14529,17 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
#endif
+ return(result);
+}
+
+mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
+ CacheEntity *rrcachestorage, mDNSu32 rrcachesize,
+ mDNSBool AdvertiseLocalAddresses, mDNSCallback *Callback, void *Context)
+{
+ mStatus result = mDNS_InitStorage(m, p, rrcachestorage, rrcachesize, AdvertiseLocalAddresses, Callback, Context);
+ if (result != mStatus_NoError)
+ return(result);
+
result = mDNSPlatformInit(m);
#ifndef UNICAST_DISABLED
@@ -14604,8 +14613,7 @@ mDNSlocal void PurgeOrReconfirmCacheRecord(mDNS *const m, CacheRecord *cr, const
mDNSlocal void mDNS_PurgeForQuestion(mDNS *const m, DNSQuestion *q)
{
- const mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
CacheRecord *rp;
mDNSu8 validatingResponse = 0;
@@ -14640,8 +14648,7 @@ mDNSlocal void mDNS_PurgeForQuestion(mDNS *const m, DNSQuestion *q)
// them.
mDNSlocal void CheckForDNSSECRecords(mDNS *const m, DNSQuestion *q)
{
- const mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
CacheRecord *rp;
for (rp = cg ? cg->members : mDNSNULL; rp; rp = rp->next)
@@ -14664,8 +14671,7 @@ mDNSlocal void CheckForDNSSECRecords(mDNS *const m, DNSQuestion *q)
mDNSexport mDNSBool mDNS_CheckForCacheRecord(mDNS *const m, DNSQuestion *q, mDNSu16 qtype)
{
DNSQuestion question;
- const mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
CacheRecord *rp;
// Create an identical question but with qtype
@@ -14788,7 +14794,7 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
// hence we are ready to ack the configuration as this is the last call to mDNSPlatformSetConfig
// for the dns configuration change notification.
SetConfigState(m, mDNStrue);
- if (!mDNSPlatformSetDNSConfig(m, mDNStrue, mDNSfalse, &fqdn, mDNSNULL, mDNSNULL, mDNStrue))
+ if (!mDNSPlatformSetDNSConfig(mDNStrue, mDNSfalse, &fqdn, mDNSNULL, mDNSNULL, mDNStrue))
{
SetDynDNSHostNameIfChanged(m, &fqdn);
SetConfigState(m, mDNSfalse);
@@ -14844,6 +14850,9 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
// cache records and as the resGroupID is different, you can't use the cache record from the scoped DNSServer to answer the
// non-scoped question and vice versa.
//
+#if USE_DNS64
+ DNS64RestartQuestions(m);
+#endif
for (q = m->Questions; q; q=q->next)
{
if (!mDNSOpaque16IsZero(q->TargetQID))
@@ -15007,7 +15016,7 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
{
LogMsg("uDNS_SetupDNSConfig: ERROR!! Cache Record %s Active question %##s (%s) (scope:%p) pointing to DNSServer Address %#a"
" to be freed", CRDisplayString(m, cr), qptr->qname.c, DNSTypeName(qptr->qtype), qptr->InterfaceID, &ptr->addr);
- qptr->validDNSServers = zeroOpaque64;
+ qptr->validDNSServers = zeroOpaque128;
qptr->qDNSServer = mDNSNULL;
cr->resrec.rDNSServer = mDNSNULL;
}
@@ -15070,7 +15079,7 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
v4 = v6 = r = zeroAddr;
v4.type = r.type = mDNSAddrType_IPv4;
- if (mDNSPlatformGetPrimaryInterface(m, &v4, &v6, &r) == mStatus_NoError && !mDNSv4AddressIsLinkLocal(&v4.ip.v4))
+ if (mDNSPlatformGetPrimaryInterface(&v4, &v6, &r) == mStatus_NoError && !mDNSv4AddressIsLinkLocal(&v4.ip.v4))
{
mDNS_SetPrimaryInterfaceInfo(m,
!mDNSIPv4AddressIsZero(v4.ip.v4) ? &v4 : mDNSNULL,
@@ -15256,3 +15265,7 @@ mDNSexport void mDNS_FinalExit(mDNS *const m)
LogInfo("mDNS_FinalExit: done");
}
+
+#ifdef UNIT_TEST
+#include "../unittests/mdns_ut.c"
+#endif
diff --git a/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h b/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
index 81ade5c5..0e96058d 100755
--- a/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
+++ b/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
@@ -296,6 +296,11 @@ typedef mDNSOpaque48 mDNSEthAddr; // An Ethernet address is a six-byte opa
#define bit_set_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] |= (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
#define bit_clr_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] &= ~(1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
#define bit_get_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] & (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
+
+// Bit operations for opaque 128 bit quantity. Uses the 32 bit quantity(l[4]) to set and clear bits
+#define bit_set_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] |= (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
+#define bit_clr_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] &= ~(1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
+#define bit_get_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] & (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
typedef enum
{
@@ -722,7 +727,7 @@ typedef packedstruct
// Bit 6 (value 0x40) is set for answer records; clear for authority/additional records
// Bit 5 (value 0x20) is set for records received with the kDNSClass_UniqueRRSet
-enum
+typedef enum
{
kDNSRecordTypeUnregistered = 0x00, // Not currently in any list
kDNSRecordTypeDeregistering = 0x01, // Shared record about to announce its departure and leave the list
@@ -750,7 +755,7 @@ enum
kDNSRecordTypePacketNegative = 0xF0, // Pseudo-RR generated to cache non-existence results like NXDomain
kDNSRecordTypePacketUniqueMask = 0x10 // True for PacketAddUnique, PacketAnsUnique, PacketAuthUnique, kDNSRecordTypePacketNegative
-};
+} kDNSRecordTypes;
typedef packedstruct { mDNSu16 priority; mDNSu16 weight; mDNSIPPort port; domainname target; } rdataSRV;
typedef packedstruct { mDNSu16 preference; domainname exchange; } rdataMX;
@@ -1359,14 +1364,14 @@ typedef struct DNSServer
mDNSs32 penaltyTime; // amount of time this server is penalized
mDNSu32 scoped; // See the scoped enum above
mDNSu32 timeout; // timeout value for questions
- mDNSBool cellIntf; // Resolver from Cellular Interface ?
mDNSu16 resGroupID; // ID of the resolver group that contains this DNSServer
+ mDNSu8 retransDO; // Total Retransmissions for queries sent with DO option
+ mDNSBool cellIntf; // Resolver from Cellular Interface?
mDNSBool req_A; // If set, send v4 query (DNSConfig allows A queries)
mDNSBool req_AAAA; // If set, send v6 query (DNSConfig allows AAAA queries)
mDNSBool req_DO; // If set, okay to send DNSSEC queries (EDNS DO bit is supported)
- mDNSBool retransDO; // Total Retransmissions for queries sent with DO option
- mDNSBool DNSSECAware; // set if we are able to receive a response to a request
- // sent with DO option.
+ mDNSBool DNSSECAware; // Set if we are able to receive a response to a request sent with DO option.
+ mDNSBool isExpensive; // True if the interface to this server is expensive.
} DNSServer;
typedef struct
@@ -1380,9 +1385,9 @@ typedef struct
struct ResourceRecord_struct
{
- mDNSu8 RecordType; // See enum above
- mDNSu16 rrtype;
- mDNSu16 rrclass;
+ mDNSu8 RecordType; // See kDNSRecordTypes enum.
+ mDNSu16 rrtype; // See DNS_TypeValues enum.
+ mDNSu16 rrclass; // See DNS_ClassValues enum.
mDNSu32 rroriginalttl; // In seconds
mDNSu16 rdlength; // Size of the raw rdata, in bytes, in the on-the-wire format
// (In-memory storage may be larger, for structures containing 'holes', like SOA)
@@ -1595,7 +1600,7 @@ struct AuthRecord_struct
// Everywhere else in the code, the determination of whether a question is unicast is made by checking to see if TargetQID is nonzero.
#define AuthRecord_uDNS(R) ((R)->resrec.InterfaceID == mDNSInterface_Any && !(R)->ForceMCast && !IsLocalDomain((R)->resrec.name))
#define Question_uDNS(Q) ((Q)->InterfaceID == mDNSInterface_Unicast || (Q)->ProxyQuestion || \
- ((Q)->InterfaceID != mDNSInterface_LocalOnly && (Q)->InterfaceID != mDNSInterface_P2P && !(Q)->ForceMCast && !IsLocalDomain(&(Q)->qname)))
+ ((Q)->InterfaceID != mDNSInterface_LocalOnly && (Q)->InterfaceID != mDNSInterface_P2P && (Q)->InterfaceID != mDNSInterface_BLE && !(Q)->ForceMCast && !IsLocalDomain(&(Q)->qname)))
// AuthRecordLocalOnly records are registered using mDNSInterface_LocalOnly and
// AuthRecordP2P records are created by D2DServiceFound events. Both record types are kept on the same list.
@@ -1639,12 +1644,6 @@ struct CacheRecord_struct
mDNSu8 UnansweredQueries; // Number of times we've issued a query for this record without getting an answer
mDNSu8 CRDNSSECQuestion; // Set to 1 if this was created in response to a DNSSEC question
mDNSOpaque16 responseFlags; // Second 16 bit in the DNS response
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- mDNSu32 MPUnansweredQ; // Multi-packet query handling: Number of times we've seen a query for this record
- mDNSs32 MPLastUnansweredQT; // Multi-packet query handling: Last time we incremented MPUnansweredQ
- mDNSu32 MPUnansweredKA; // Multi-packet query handling: Number of times we've seen this record in a KA list
- mDNSBool MPExpectingKA; // Multi-packet query handling: Set when we increment MPUnansweredQ; allows one KA
-#endif
CacheRecord *NextInCFList; // Set if this is in the list of records we just received with the cache flush bit set
CacheRecord *nsec; // NSEC records needed for non-existence proofs
CacheRecord *soa; // SOA record to return for proxy questions
@@ -1897,7 +1896,9 @@ typedef enum { DNSSECValNotRequired = 0, DNSSECValRequired, DNSSECValInProgress,
// RFC 4122 defines it to be 16 bytes
#define UUID_SIZE 16
-#if TARGET_OS_EMBEDDED
+#define AWD_METRICS (USE_AWD && TARGET_OS_EMBEDDED)
+
+#if AWD_METRICS
typedef struct
{
domainname * originalQName; // Name of original A/AAAA record if this question is for a CNAME record.
@@ -1906,10 +1907,18 @@ typedef struct
mDNSBool answered; // Has this question been answered?
} uDNSMetrics;
-
+#endif
+
+// DNS64 code is only for iOS, which is currently the only Apple OS that supports DNS proxy network extensions.
+#define USE_DNS64 (HAVE_DNS64 && TARGET_OS_IOS)
+
+#if USE_DNS64
+#include "DNS64State.h"
+#endif
+
+#if TARGET_OS_EMBEDDED
extern mDNSu32 curr_num_regservices; // tracks the current number of services registered
extern mDNSu32 max_num_regservices; // tracks the max number of simultaneous services registered by the device
-
#endif
struct DNSQuestion_struct
@@ -1964,7 +1973,7 @@ struct DNSQuestion_struct
// |-> DNS Configuration related fields used in uDNS (Subset of Wide Area/Unicast fields)
DNSServer *qDNSServer; // Caching server for this query (in the absence of an SRV saying otherwise)
- mDNSOpaque64 validDNSServers; // Valid DNSServers for this question
+ mDNSOpaque128 validDNSServers; // Valid DNSServers for this question
mDNSu16 noServerResponse; // At least one server did not respond.
mDNSu16 triedAllServersOnce; // Tried all DNS servers once
mDNSu8 unansweredQueries; // The number of unanswered queries to this server
@@ -2033,6 +2042,9 @@ struct DNSQuestion_struct
#if TARGET_OS_EMBEDDED
uDNSMetrics metrics; // Data used for collecting unicast DNS query metrics.
#endif
+#if USE_DNS64
+ DNS64 dns64; // DNS64 state for performing IPv6 address synthesis on networks with NAT64.
+#endif
};
typedef enum { ZoneServiceUpdate, ZoneServiceQuery, ZoneServiceLLQ, ZoneServiceDNSPush } ZoneService;
@@ -2281,6 +2293,10 @@ struct mDNS_DNSPushNotificationZone
} ;
+// Time constant (~= 260 hours ~= 10 days and 21 hours) used to set
+// various time values to a point well into the future.
+#define FutureTime 0x38000000
+
struct mDNS_struct
{
// Internal state fields. These hold the main internal state of mDNSCore;
@@ -2346,9 +2362,6 @@ struct mDNS_struct
// during which underying platform layer should inhibit system sleep
mDNSs32 TimeSlept; // Time we went to sleep.
- mDNSs32 StatStartTime; // Time we started gathering statistics during this interval.
- mDNSs32 NextStatLogTime; // Next time to log statistics.
- mDNSs32 ActiveStatTime; // Total time awake/gathering statistics for this log period.
mDNSs32 UnicastPacketsSent; // Number of unicast packets sent.
mDNSs32 MulticastPacketsSent; // Number of multicast packets sent.
mDNSs32 RemoteSubnet; // Multicast packets received from outside our subnet.
@@ -2445,11 +2458,11 @@ struct mDNS_struct
mDNSBool SSDPWANPPPConnection; // whether we should send the SSDP query for WANIPConnection or WANPPPConnection
mDNSIPPort UPnPRouterPort; // port we send discovery messages to
mDNSIPPort UPnPSOAPPort; // port we send SOAP messages to
- mDNSu8 *UPnPRouterURL; // router's URL string
+ char *UPnPRouterURL; // router's URL string
mDNSBool UPnPWANPPPConnection; // whether we're using WANIPConnection or WANPPPConnection
- mDNSu8 *UPnPSOAPURL; // router's SOAP control URL string
- mDNSu8 *UPnPRouterAddressString; // holds both the router's address and port
- mDNSu8 *UPnPSOAPAddressString; // holds both address and port for SOAP messages
+ char *UPnPSOAPURL; // router's SOAP control URL string
+ char *UPnPRouterAddressString; // holds both the router's address and port
+ char *UPnPSOAPAddressString; // holds both address and port for SOAP messages
// DNS Push Notification fields
DNSPushNotificationServer *DNSPushServers; // DNS Push Notification Servers
@@ -2476,7 +2489,6 @@ struct mDNS_struct
#if APPLE_OSX_mDNSResponder
ClientTunnel *TunnelClients;
- uuid_t asl_uuid; // uuid for ASL logging
void *WCF;
#endif
// DNS Proxy fields
@@ -2569,7 +2581,8 @@ extern const mDNSOpaque16 SubscribeFlags;
extern const mDNSOpaque16 UnSubscribeFlags;
extern const mDNSOpaque64 zeroOpaque64;
-
+extern const mDNSOpaque128 zeroOpaque128;
+
extern mDNSBool StrictUnicastOrdering;
extern mDNSu8 NumUnicastDNSServers;
#if APPLE_OSX_mDNSResponder
@@ -2762,17 +2775,6 @@ typedef enum { mDNS_Dereg_normal, mDNS_Dereg_rapid, mDNS_Dereg_conflict, mDNS_De
extern void mDNS_SetupResourceRecord(AuthRecord *rr, RData *RDataStorage, mDNSInterfaceID InterfaceID,
mDNSu16 rrtype, mDNSu32 ttl, mDNSu8 RecordType, AuthRecType artype, mDNSRecordCallback Callback, void *Context);
-// mDNS_RegisterService() flags parameter bit definitions.
-// Note these are only defined to transfer the corresponding DNSServiceFlags settings into mDNSCore routines,
-// since code in mDNSCore does not include the DNSServiceFlags definitions in dns_sd.h.
-enum
-{
- coreFlagIncludeP2P = 0x1, // include P2P interfaces when using mDNSInterface_Any
- coreFlagIncludeAWDL = 0x2, // include AWDL interface when using mDNSInterface_Any
- coreFlagKnownUnique = 0x4, // client guarantees that SRV and TXT record names are unique
- coreFlagWakeOnly = 0x8 // Service won't be registered with sleep proxy
-};
-
extern mDNSu32 deriveD2DFlagsFromAuthRecType(AuthRecType authRecType);
extern mStatus mDNS_RegisterService (mDNS *const m, ServiceRecordSet *sr,
const domainlabel *const name, const domainname *const type, const domainname *const domain,
@@ -2900,6 +2902,10 @@ extern char *ConvertDomainNameToCString_withescape(const domainname *const na
extern void ConvertUTF8PstringToRFC1034HostLabel(const mDNSu8 UTF8Name[], domainlabel *const hostlabel);
+#define ValidTransportProtocol(X) ( (X)[0] == 4 && (X)[1] == '_' && \
+ ((((X)[2] | 0x20) == 'u' && ((X)[3] | 0x20) == 'd') || (((X)[2] | 0x20) == 't' && ((X)[3] | 0x20) == 'c')) && \
+ ((X)[4] | 0x20) == 'p')
+
extern mDNSu8 *ConstructServiceName(domainname *const fqdn, const domainlabel *name, const domainname *type, const domainname *const domain);
extern mDNSBool DeconstructServiceName(const domainname *const fqdn, domainlabel *const name, domainname *const type, domainname *const domain);
@@ -2955,6 +2961,7 @@ extern mDNSBool mDNSAddrIPv4FromMappedIPv6(mDNSv6Addr *in, mDNSv4Addr *out);
#define mDNSIPPortIsZero(A) ((A).NotAnInteger == 0)
#define mDNSOpaque16IsZero(A) ((A).NotAnInteger == 0)
#define mDNSOpaque64IsZero(A) (((A)->l[0] | (A)->l[1] ) == 0)
+#define mDNSOpaque128IsZero(A) (((A)->l[0] | (A)->l[1] | (A)->l[2] | (A)->l[3]) == 0)
#define mDNSIPv4AddressIsZero(A) ((A).NotAnInteger == 0)
#define mDNSIPv6AddressIsZero(A) (((A).l[0] | (A).l[1] | (A).l[2] | (A).l[3]) == 0)
#define mDNSEthAddressIsZero(A) (((A).w[0] | (A).w[1] | (A).w[2] ) == 0)
@@ -2989,12 +2996,6 @@ extern mDNSBool mDNSAddrIPv4FromMappedIPv6(mDNSv6Addr *in, mDNSv4Addr *out);
((X)->type == mDNSAddrType_IPv4) ? mDNSv4AddressIsLinkLocal(&(X)->ip.v4) : \
((X)->type == mDNSAddrType_IPv6) ? mDNSv6AddressIsLinkLocal(&(X)->ip.v6) : mDNSfalse)
-#define mDNSv4AddressIsLoopback(X) ((X)->b[0] == 127 && (X)->b[1] == 0 && (X)->b[2] == 0 && (X)->b[3] == 1)
-#define mDNSv6AddressIsLoopback(X) ((((X)->l[0] | (X)->l[1] | (X)->l[2]) == 0) && ((X)->b[12] == 0 && (X)->b[13] == 0 && (X)->b[14] == 0 && (X)->b[15] == 1))
-
-#define mDNSAddressIsLoopback(X) ( \
- ((X)->type == mDNSAddrType_IPv4) ? mDNSv4AddressIsLoopback(&(X)->ip.v4) : \
- ((X)->type == mDNSAddrType_IPv6) ? mDNSv6AddressIsLoopback(&(X)->ip.v6) : mDNSfalse)
// ***************************************************************************
#if 0
@@ -3038,8 +3039,8 @@ extern void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCa
extern void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn);
extern void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, const mDNSAddr *v6addr, const mDNSAddr *router);
extern DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, mDNSs32 serviceID, const mDNSAddr *addr,
- const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSu16 resGroupID, mDNSBool reqA,
- mDNSBool reqAAAA, mDNSBool reqDO);
+ const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSu16 resGroupID,
+ mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO);
extern void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 responseFlags);
extern void mDNS_AddSearchDomain(const domainname *const domain, mDNSInterfaceID InterfaceID);
@@ -3157,17 +3158,6 @@ extern void mDNSPlatformWriteDebugMsg(const char *msg);
#endif
extern void mDNSPlatformWriteLogMsg(const char *ident, const char *msg, mDNSLogLevel_t loglevel);
-#if APPLE_OSX_mDNSResponder
-// Utility function for ASL logging
-mDNSexport void mDNSASLLog(uuid_t *uuid, const char *subdomain, const char *result, const char *signature, const char *fmt, ...);
-
-// Log unicast and multicast traffic statistics once a day. Also used for DNSSEC statistics.
-#define kDefaultNextStatsticsLogTime (24 * 60 * 60)
-
-extern void mDNSLogStatistics(mDNS *const m);
-
-#endif // APPLE_OSX_mDNSResponder
-
// Platform support modules should provide the following functions to map between opaque interface IDs
// and interface indexes in order to support the DNS-SD API. If your target platform does not support
// multiple interfaces and/or does not support the DNS-SD API, these functions can be empty.
@@ -3198,7 +3188,7 @@ typedef enum
} TCPSocketFlags;
typedef void (*TCPConnectionCallback)(TCPSocket *sock, void *context, mDNSBool ConnectionEstablished, mStatus err);
-extern TCPSocket *mDNSPlatformTCPSocket(mDNS *const m, TCPSocketFlags flags, mDNSIPPort *port, mDNSBool useBackgroundTrafficClass); // creates a TCP socket
+extern TCPSocket *mDNSPlatformTCPSocket(TCPSocketFlags flags, mDNSIPPort *port, mDNSBool useBackgroundTrafficClass); // creates a TCP socket
extern TCPSocket *mDNSPlatformTCPAccept(TCPSocketFlags flags, int sd);
extern int mDNSPlatformTCPGetFD(TCPSocket *sock);
extern mStatus mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr *dst, mDNSOpaque16 dstport, domainname *hostname,
@@ -3206,17 +3196,18 @@ extern mStatus mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr *dst, m
extern void mDNSPlatformTCPCloseConnection(TCPSocket *sock);
extern long mDNSPlatformReadTCP(TCPSocket *sock, void *buf, unsigned long buflen, mDNSBool *closed);
extern long mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned long len);
-extern UDPSocket *mDNSPlatformUDPSocket(mDNS *const m, const mDNSIPPort requestedport);
+extern UDPSocket *mDNSPlatformUDPSocket(const mDNSIPPort requestedport);
extern mDNSu16 mDNSPlatformGetUDPPort(UDPSocket *sock);
extern void mDNSPlatformUDPClose(UDPSocket *sock);
-extern void mDNSPlatformReceiveBPF_fd(mDNS *const m, int fd);
-extern void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID);
+extern mDNSBool mDNSPlatformUDPSocketEncounteredEOF(const UDPSocket *sock);
+extern void mDNSPlatformReceiveBPF_fd(int fd);
+extern void mDNSPlatformUpdateProxyList(const mDNSInterfaceID InterfaceID);
extern void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID);
-extern void mDNSPlatformSetLocalAddressCacheEntry(mDNS *const m, const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID);
+extern void mDNSPlatformSetLocalAddressCacheEntry(const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID);
extern void mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAddr *const dst);
extern void mDNSPlatformSendKeepalive(mDNSAddr *sadd, mDNSAddr *dadd, mDNSIPPort *lport, mDNSIPPort *rport, mDNSu32 seq, mDNSu32 ack, mDNSu16 win);
-extern mStatus mDNSPlatformRetrieveTCPInfo(mDNS *const m, mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti);
-extern mStatus mDNSPlatformGetRemoteMacAddr(mDNS *const m, mDNSAddr *raddr);
+extern mStatus mDNSPlatformRetrieveTCPInfo(mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti);
+extern mStatus mDNSPlatformGetRemoteMacAddr(mDNSAddr *raddr);
extern mStatus mDNSPlatformStoreSPSMACAddr(mDNSAddr *spsaddr, char *ifname);
extern mStatus mDNSPlatformClearSPSData(void);
extern mStatus mDNSPlatformStoreOwnerOptRecord(char *ifname, DNSMessage *msg, int length);
@@ -3228,14 +3219,14 @@ extern void mDNSPlatformTLSTearDownCerts(void);
// Platforms that support unicast browsing and dynamic update registration for clients who do not specify a domain
// in browse/registration calls must implement these routines to get the "default" browse/registration list.
-extern mDNSBool mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
+extern mDNSBool mDNSPlatformSetDNSConfig(mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
DNameListElem **BrowseDomains, mDNSBool ackConfig);
-extern mStatus mDNSPlatformGetPrimaryInterface(mDNS *const m, mDNSAddr *v4, mDNSAddr *v6, mDNSAddr *router);
+extern mStatus mDNSPlatformGetPrimaryInterface(mDNSAddr *v4, mDNSAddr *v6, mDNSAddr *router);
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 void mDNSPlatformSetAllowSleep(mDNSBool allowSleep, const char *reason);
+extern void mDNSPlatformPreventSleep(mDNSu32 timeout, const char *reason);
+extern void mDNSPlatformSendWakeupPacket(mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration);
extern mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID);
extern mDNSBool mDNSPlatformInterfaceIsAWDL(const NetworkInterfaceInfo *intf);
@@ -3293,8 +3284,17 @@ extern void LNT_ClearState(mDNS *const m);
extern void mDNS_SetFQDN(mDNS *const m);
extern void mDNS_ActivateNetWake_internal (mDNS *const m, NetworkInterfaceInfo *set);
extern void mDNS_DeactivateNetWake_internal(mDNS *const m, NetworkInterfaceInfo *set);
-extern mStatus mDNS_RegisterInterface (mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping);
-extern void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping);
+
+// Attributes that controls the Bonjour operation initiation and response speed for an interface.
+typedef enum
+{
+ FastActivation, // For p2p* and DirectLink type interfaces
+ NormalActivation, // For standard interface timing
+ SlowActivation // For flapping interfaces
+} InterfaceActivationSpeed;
+
+extern mStatus mDNS_RegisterInterface (mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed probeDelay);
+extern void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed probeDelay);
extern void mDNSCoreInitComplete(mDNS *const m, mStatus result);
extern void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
const mDNSAddr *const srcaddr, const mDNSIPPort srcport,
@@ -3316,7 +3316,7 @@ extern void mDNSCoreReceiveRawPacket (mDNS *const m, const mDNSu8 *const p,
extern mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip);
extern CacheRecord *CreateNewCacheEntry(mDNS *const m, const mDNSu32 slot, CacheGroup *cg, mDNSs32 delay, mDNSBool Add, const mDNSAddr *sourceAddress);
-extern CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name);
+extern CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 namehash, const domainname *const name);
extern void ReleaseCacheRecord(mDNS *const m, CacheRecord *r);
extern void ScheduleNextCacheCheckTime(mDNS *const m, const mDNSu32 slot, const mDNSs32 event);
extern void SetNextCacheCheckTimeForRecord(mDNS *const m, CacheRecord *const rr);
@@ -3340,8 +3340,8 @@ extern void UpdateRMAC(mDNS *const m, void *context);
// Used only in logging to restrict the number of /etc/hosts entries printed
extern void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result);
// exported for using the hash for /etc/hosts AuthRecords
-extern AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name);
-extern AuthGroup *AuthGroupForRecord(AuthHash *r, const mDNSu32 slot, const ResourceRecord *const rr);
+extern AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 namehash, const domainname *const name);
+extern AuthGroup *AuthGroupForRecord(AuthHash *r, const ResourceRecord *const rr);
extern AuthGroup *InsertAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr);
extern AuthGroup *RemoveAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr);
extern mDNSBool mDNS_CheckForCacheRecord(mDNS *const m, DNSQuestion *q, mDNSu16 qtype);
@@ -3350,35 +3350,36 @@ extern mDNSBool mDNS_CheckForCacheRecord(mDNS *const m, DNSQuestion *q, mDNSu16
// In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer
#if APPLE_OSX_mDNSResponder
extern void AutoTunnelCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord);
-extern void AddNewClientTunnel(mDNS *const m, DNSQuestion *const q);
-extern void StartServerTunnel(mDNS *const m, DomainAuthInfo *const info);
+extern void AddNewClientTunnel(DNSQuestion *const q);
+extern void StartServerTunnel(DomainAuthInfo *const info);
extern void UpdateAutoTunnelDomainStatuses(const mDNS *const m);
extern void RemoveAutoTunnel6Record(mDNS *const m);
-extern mDNSBool RecordReadyForSleep(mDNS *const m, AuthRecord *rr);
+extern mDNSBool RecordReadyForSleep(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, mDNSBool *keepaliveOnly);
-extern void mDNSPlatformUpdateDNSStatus(mDNS *const m, DNSQuestion *q);
-extern void mDNSPlatformTriggerDNSRetry(mDNS *const m, DNSQuestion *v4q, DNSQuestion *v6q);
+extern mStatus ActivateLocalProxy(NetworkInterfaceInfo *const intf, mDNSBool *keepaliveOnly);
+extern void mDNSPlatformUpdateDNSStatus(DNSQuestion *q);
+extern void mDNSPlatformTriggerDNSRetry(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, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
+typedef void ProxyCallback (void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context);
-extern void mDNSPlatformInitDNSProxySkts(mDNS *const m, ProxyCallback *UDPCallback, ProxyCallback *TCPCallback);
+extern void mDNSPlatformInitDNSProxySkts(ProxyCallback *UDPCallback, ProxyCallback *TCPCallback);
extern void mDNSPlatformCloseDNSProxySkts(mDNS *const m);
extern void mDNSPlatformDisposeProxyContext(void *context);
extern mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DNSMessage *msg, mDNSu8 *start, mDNSu8 *limit);
#if APPLE_OSX_mDNSResponder
-extern void mDNSPlatformGetDNSRoutePolicy(mDNS *const m, DNSQuestion *q, mDNSBool *isBlocked);
+extern void mDNSPlatformGetDNSRoutePolicy(DNSQuestion *q, mDNSBool *isBlocked);
#endif
extern void mDNSPlatformSetSocktOpt(void *sock, mDNSTransport_Type transType, mDNSAddr_Type addrType, const DNSQuestion *q);
extern mDNSs32 mDNSPlatformGetPID(void);
extern mDNSBool mDNSValidKeepAliveRecord(AuthRecord *rr);
+extern mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
// ***************************************************************************
#if 0
@@ -3600,17 +3601,17 @@ 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) <= 894) ? 1 : -1];
+ char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 912) ? 1 : -1];
- char sizecheck_ZoneData [(sizeof(ZoneData) <= 1730) ? 1 : -1];
+ char sizecheck_ZoneData [(sizeof(ZoneData) <= 1744) ? 1 : -1];
char sizecheck_NATTraversalInfo [(sizeof(NATTraversalInfo) <= 200) ? 1 : -1];
char sizecheck_HostnameInfo [(sizeof(HostnameInfo) <= 3050) ? 1 : -1];
char sizecheck_DNSServer [(sizeof(DNSServer) <= 330) ? 1 : -1];
- char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 7272) ? 1 : -1];
+ char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 7376) ? 1 : -1];
char sizecheck_ServiceRecordSet [(sizeof(ServiceRecordSet) <= 5540) ? 1 : -1];
char sizecheck_DomainAuthInfo [(sizeof(DomainAuthInfo) <= 7888) ? 1 : -1];
#if APPLE_OSX_mDNSResponder
- char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1230) ? 1 : -1];
+ char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1256) ? 1 : -1];
#endif
};
diff --git a/mDNSResponder/mDNSCore/nsec.c b/mDNSResponder/mDNSCore/nsec.c
index 09d27356..31cf1e95 100644
--- a/mDNSResponder/mDNSCore/nsec.c
+++ b/mDNSResponder/mDNSCore/nsec.c
@@ -56,12 +56,10 @@ mDNSlocal CacheRecord *NSECParentForQuestion(mDNS *const m, DNSQuestion *q)
{
CacheGroup *cg;
CacheRecord *cr;
- mDNSu32 slot;
mDNSu32 namehash;
- slot = HashSlot(&q->qname);
namehash = DomainNameHashValue(&q->qname);
- cg = CacheGroupForName(m, slot, namehash, &q->qname);
+ cg = CacheGroupForName(m, namehash, &q->qname);
if (!cg)
{
LogDNSSEC("NSECParentForQuestion: Cannot find cg for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
@@ -1050,12 +1048,11 @@ mDNSexport CacheRecord *NSECRecordIsDelegation(mDNS *const m, domainname *name,
{
CacheGroup *cg;
CacheRecord *cr;
- mDNSu32 slot, namehash;
+ mDNSu32 namehash;
- slot = HashSlot(name);
namehash = DomainNameHashValue(name);
- cg = CacheGroupForName(m, (const mDNSu32)slot, namehash, name);
+ cg = CacheGroupForName(m, namehash, name);
if (!cg)
{
LogDNSSEC("NSECRecordForName: cg NULL for %##s", name);
diff --git a/mDNSResponder/mDNSCore/nsec3.c b/mDNSResponder/mDNSCore/nsec3.c
index 4e9e8c82..43cd37a8 100644
--- a/mDNSResponder/mDNSCore/nsec3.c
+++ b/mDNSResponder/mDNSCore/nsec3.c
@@ -675,12 +675,11 @@ mDNSexport CacheRecord *NSEC3RecordIsDelegation(mDNS *const m, domainname *name,
CacheGroup *cg;
CacheRecord *cr;
CacheRecord *ncr;
- mDNSu32 slot, namehash;
+ mDNSu32 namehash;
- slot = HashSlot(name);
namehash = DomainNameHashValue(name);
- cg = CacheGroupForName(m, (const mDNSu32)slot, namehash, name);
+ cg = CacheGroupForName(m, namehash, name);
if (!cg)
{
LogDNSSEC("NSEC3RecordForName: cg NULL for %##s", name);
diff --git a/mDNSResponder/mDNSCore/uDNS.c b/mDNSResponder/mDNSCore/uDNS.c
index 3677b9f7..dc87724c 100755
--- a/mDNSResponder/mDNSCore/uDNS.c
+++ b/mDNSResponder/mDNSCore/uDNS.c
@@ -45,12 +45,12 @@ mDNSexport SearchListElem *SearchList = mDNSNULL;
mDNSBool StrictUnicastOrdering = mDNSfalse;
// We keep track of the number of unicast DNS servers and log a message when we exceed 64.
-// Currently the unicast queries maintain a 64 bit map to track the valid DNS servers for that
+// Currently the unicast queries maintain a 128 bit map to track the valid DNS servers for that
// question. Bit position is the index into the DNS server list. This is done so to try all
// the servers exactly once before giving up. If we could allocate memory in the core, then
-// arbitrary limitation of 64 DNSServers can be removed.
+// arbitrary limitation of 128 DNSServers can be removed.
mDNSu8 NumUnicastDNSServers = 0;
-#define MAX_UNICAST_DNS_SERVERS 64
+#define MAX_UNICAST_DNS_SERVERS 128
#if APPLE_OSX_mDNSResponder
mDNSu8 NumUnreachableDNSServers = 0;
#endif
@@ -112,8 +112,8 @@ mDNSlocal void SetRecordRetry(mDNS *const m, AuthRecord *rr, mDNSu32 random)
#endif
mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSs32 serviceID, const mDNSAddr *addr,
- const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSu16 resGroupID, mDNSBool reqA,
- mDNSBool reqAAAA, mDNSBool reqDO)
+ const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSu16 resGroupID,
+ mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO)
{
DNSServer **p = &m->DNSServers;
DNSServer *tmp = mDNSNULL;
@@ -127,9 +127,9 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
if (!d)
d = (const domainname *)"";
- LogInfo("mDNS_AddDNSServer(%d): Adding %#a for %##s, InterfaceID %p, serviceID %u, scoped %d, resGroupID %d req_A is %s req_AAAA is %s cell %s req_DO is %s",
+ LogInfo("mDNS_AddDNSServer(%d): Adding %#a for %##s, InterfaceID %p, serviceID %u, scoped %d, resGroupID %d req_A is %s req_AAAA is %s cell %s isExpensive %s req_DO is %s",
NumUnicastDNSServers, addr, d->c, interface, serviceID, scoped, resGroupID, reqA ? "True" : "False", reqAAAA ? "True" : "False",
- cellIntf ? "True" : "False", reqDO ? "True" : "False");
+ cellIntf ? "True" : "False", isExpensive ? "True" : "False", reqDO ? "True" : "False");
mDNS_CheckLock(m);
@@ -186,17 +186,18 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
}
else
{
- (*p)->scoped = scoped;
- (*p)->interface = interface;
- (*p)->serviceID = serviceID;
- (*p)->addr = *addr;
- (*p)->port = port;
- (*p)->flags = DNSServer_FlagNew;
- (*p)->timeout = timeout;
- (*p)->cellIntf = cellIntf;
- (*p)->req_A = reqA;
- (*p)->req_AAAA = reqAAAA;
- (*p)->req_DO = reqDO;
+ (*p)->scoped = scoped;
+ (*p)->interface = interface;
+ (*p)->serviceID = serviceID;
+ (*p)->addr = *addr;
+ (*p)->port = port;
+ (*p)->flags = DNSServer_FlagNew;
+ (*p)->timeout = timeout;
+ (*p)->cellIntf = cellIntf;
+ (*p)->isExpensive = isExpensive;
+ (*p)->req_A = reqA;
+ (*p)->req_AAAA = reqAAAA;
+ (*p)->req_DO = reqDO;
// We start off assuming that the DNS server is not DNSSEC aware and
// when we receive the first response to a DNSSEC question, we set
// it to true.
@@ -485,7 +486,7 @@ mDNSlocal mStatus uDNS_RequestAddress(mDNS *m)
if (!m->NATTraversals)
{
- m->retryGetAddr = NonZeroTime(m->timenow + 0x78000000);
+ m->retryGetAddr = NonZeroTime(m->timenow + FutureTime);
LogInfo("uDNS_RequestAddress: Setting retryGetAddr to future");
}
else if (m->timenow - m->retryGetAddr >= 0)
@@ -1554,7 +1555,7 @@ mDNSlocal tcpInfo_t *MakeTCPConn(mDNS *const m, const DNSMessage *const msg, con
mDNSPlatformMemZero(info, sizeof(tcpInfo_t));
info->m = m;
- info->sock = mDNSPlatformTCPSocket(m, flags, &srcport, useBackgroundTrafficClass);
+ info->sock = mDNSPlatformTCPSocket(flags, &srcport, useBackgroundTrafficClass);
info->requestLen = 0;
info->question = question;
info->rr = rr;
@@ -1720,7 +1721,7 @@ mDNSexport const domainname *GetServiceTarget(mDNS *m, AuthRecord *const rr)
DomainAuthInfo *AuthInfo = GetAuthInfoForName_internal(m, rr->resrec.name);
if (AuthInfo && AuthInfo->AutoTunnel)
{
- StartServerTunnel(m, AuthInfo);
+ StartServerTunnel(AuthInfo);
if (AuthInfo->AutoTunnelHostRecord.namestorage.c[0] == 0) return(mDNSNULL);
debugf("GetServiceTarget: Returning %##s", AuthInfo->AutoTunnelHostRecord.namestorage.c);
return(&AuthInfo->AutoTunnelHostRecord.namestorage);
@@ -2759,7 +2760,6 @@ mDNSexport void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, co
m->NextSRVUpdate = NonZeroTime(m->timenow);
#if APPLE_OSX_mDNSResponder
- if (RouterChanged) uuid_generate(m->asl_uuid);
UpdateAutoTunnelDomainStatuses(m);
#endif
}
@@ -3034,7 +3034,6 @@ exit:
mDNSlocal mDNSBool IsRecordMergeable(mDNS *const m, AuthRecord *rr, mDNSs32 time)
{
DomainAuthInfo *info;
- (void) m; //unused
// A record is eligible for merge, if the following properties are met.
//
// 1. uDNS Resource Record
@@ -3697,9 +3696,7 @@ mDNSlocal void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID Interface
if (AddrReply->opcode == NATOp_AddrResponse)
{
#if APPLE_OSX_mDNSResponder
- static char msgbuf[16];
- mDNS_snprintf(msgbuf, sizeof(msgbuf), "%d", AddrReply->err);
- mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.natpmp.AddressRequest", AddrReply->err ? "failure" : "success", msgbuf, "");
+ LogInfo("uDNS_ReceiveNATPMPPacket: AddressRequest %s error %d", AddrReply->err ? "failure" : "success", AddrReply->err);
#endif
if (!AddrReply->err && len < sizeof(NATAddrReply)) { LogMsg("NAT-PMP AddrResponse message too short (%d bytes)", len); return; }
natTraversalHandleAddressReply(m, AddrReply->err, AddrReply->ExtAddr);
@@ -3708,9 +3705,8 @@ mDNSlocal void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID Interface
{
mDNSu8 Protocol = AddrReply->opcode & 0x7F;
#if APPLE_OSX_mDNSResponder
- static char msgbuf[16];
- mDNS_snprintf(msgbuf, sizeof(msgbuf), "%s - %d", AddrReply->opcode == NATOp_MapUDPResponse ? "UDP" : "TCP", PortMapReply->err);
- mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.natpmp.PortMapRequest", PortMapReply->err ? "failure" : "success", msgbuf, "");
+ LogInfo("uDNS_ReceiveNATPMPPacket: PortMapRequest %s %s - error %d",
+ PortMapReply->err ? "failure" : "success", (AddrReply->opcode == NATOp_MapUDPResponse) ? "UDP" : "TCP", PortMapReply->err);
#endif
if (!PortMapReply->err)
{
@@ -3921,7 +3917,9 @@ mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNS
if (QR_OP == UpdateR)
{
- mDNSu32 lease = GetPktLease(m, msg, end);
+ mDNSu32 pktlease = 0;
+ mDNSBool gotlease = GetPktLease(m, msg, end, &pktlease);
+ mDNSu32 lease = gotlease ? pktlease : 60 * 60; // If lease option missing, assume one hour
mDNSs32 expire = m->timenow + (mDNSs32)lease * mDNSPlatformOneSecond;
mDNSu32 random = mDNSRandom((mDNSs32)lease * mDNSPlatformOneSecond/10);
@@ -4088,6 +4086,7 @@ mDNSexport void LLQGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneI
mDNS_Unlock(m);
}
+#ifdef DNS_PUSH_ENABLED
mDNSexport void DNSPushNotificationGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo)
{
DNSQuestion *q = (DNSQuestion *)zoneInfo->ZoneDataContext;
@@ -4120,7 +4119,7 @@ mDNSexport void DNSPushNotificationGotZoneData(mDNS *const m, mStatus err, const
}
mDNS_Unlock(m);
}
-
+#endif // DNS_PUSH_ENABLED
// Called in normal callback context (i.e. mDNS_busy and mDNS_reentrancy are both 1)
mDNSlocal void PrivateQueryGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo)
@@ -4625,9 +4624,11 @@ mDNSlocal void handle_unanswered_query(mDNS *const m)
mDNSlocal void uDNS_HandleLLQState(mDNS *const m, DNSQuestion *q)
{
+#ifdef DNS_PUSH_ENABLED
// First attempt to use DNS Push Notification.
if (q->dnsPushState == DNSPUSH_INIT)
DiscoverDNSPushNotificationServer(m, q);
+#endif // DNS_PUSH_ENABLED
switch (q->state)
{
case LLQ_InitialRequest: startLLQHandshake(m, q); break;
@@ -4733,9 +4734,20 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
debugf("uDNS_CheckCurrentQuestion sending %p %##s (%s) %#a:%d UnansweredQueries %d",
q, q->qname.c, DNSTypeName(q->qtype),
q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL, mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zeroIPPort), q->unansweredQueries);
+#if APPLE_OSX_mDNSResponder
+ // When a DNS proxy network extension initiates the close of a UDP flow (this usually happens when a DNS
+ // proxy gets disabled or crashes), mDNSResponder's corresponding UDP socket will be marked with the
+ // SS_CANTRCVMORE state flag. Reading from such a socket is no longer possible, so close the current
+ // socket pair so that we can create a new pair.
+ if (q->LocalSocket && mDNSPlatformUDPSocketEncounteredEOF(q->LocalSocket))
+ {
+ mDNSPlatformUDPClose(q->LocalSocket);
+ q->LocalSocket = mDNSNULL;
+ }
+#endif
if (!q->LocalSocket)
{
- q->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
+ q->LocalSocket = mDNSPlatformUDPSocket(zeroIPPort);
if (q->LocalSocket)
{
mDNSPlatformSetSocktOpt(q->LocalSocket, mDNSTransport_UDP, mDNSAddrType_IPv4, q);
@@ -4777,8 +4789,18 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
}
newServer = GetServerForQuestion(m, q);
- DNSServerChangeForQuestion(m, q, newServer);
-
+ if (!newServer)
+ {
+ q->triedAllServersOnce = 1;
+ SetValidDNSServers(m, q);
+ newServer = GetServerForQuestion(m, q);
+ }
+ if (newServer)
+ {
+ LogInfo("uDNS_checkCurrentQuestion: Retrying question %p %##s (%s) DNS Server %#a:%u ThisQInterval %d",
+ q, q->qname.c, DNSTypeName(q->qtype), newServer ? &newServer->addr : mDNSNULL, mDNSVal16(newServer ? newServer->port : zeroIPPort), q->ThisQInterval);
+ DNSServerChangeForQuestion(m, q, newServer);
+ }
if (q->triedAllServersOnce)
{
q->LastQTime = m->timenow;
@@ -4789,7 +4811,6 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
q->LastQTime = m->timenow - q->ThisQInterval;
}
q->unansweredQueries = 0;
- q->noServerResponse = 1;
}
else
{
@@ -4839,20 +4860,20 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
// passed to uDNS_CheckCurrentQuestion -- we only want one set of query packets hitting the wire --
// but we want *all* of the questions to get answer callbacks.)
CacheRecord *rr;
- const mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ const mDNSu32 slot = HashSlotFromNameHash(q->qnamehash);
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
if (!q->qDNSServer)
{
- if (!mDNSOpaque64IsZero(&q->validDNSServers))
- LogMsg("uDNS_CheckCurrentQuestion: ERROR!!: valid DNSServer bits not zero 0x%x, 0x%x for question %##s (%s)",
- q->validDNSServers.l[1], q->validDNSServers.l[0], q->qname.c, DNSTypeName(q->qtype));
+ if (!mDNSOpaque128IsZero(&q->validDNSServers))
+ LogMsg("uDNS_CheckCurrentQuestion: ERROR!!: valid DNSServer bits not zero 0x%x, 0x%x 0x%x 0x%x for question %##s (%s)",
+ q->validDNSServers.l[3], q->validDNSServers.l[2], q->validDNSServers.l[1], q->validDNSServers.l[0], q->qname.c, DNSTypeName(q->qtype));
// If we reached the end of list while picking DNS servers, then we don't want to deactivate the
// question. Try after 60 seconds. We find this by looking for valid DNSServers for this question,
// if we find any, then we must have tried them before we came here. This avoids maintaining
// another state variable to see if we had valid DNS servers for this question.
SetValidDNSServers(m, q);
- if (mDNSOpaque64IsZero(&q->validDNSServers))
+ if (mDNSOpaque128IsZero(&q->validDNSServers))
{
LogInfo("uDNS_CheckCurrentQuestion: no DNS server for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
q->ThisQInterval = 0;
@@ -4916,7 +4937,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
{
mDNSBool rfc1918 = mDNSv4AddrIsRFC1918(&m->AdvertisedV4.ip.v4);
mDNSBool HaveRoutable = !rfc1918 && !mDNSIPv4AddressIsZero(m->AdvertisedV4.ip.v4);
- m->NextScheduledNATOp = m->timenow + 0x3FFFFFFF;
+ m->NextScheduledNATOp = m->timenow + FutureTime;
if (HaveRoutable) m->ExtAddress = m->AdvertisedV4.ip.v4;
@@ -4926,7 +4947,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
{
// we need to log a message if we can't get our socket, but only the first time (after success)
static mDNSBool needLog = mDNStrue;
- m->NATMcastRecvskt = mDNSPlatformUDPSocket(m, NATPMPAnnouncementPort);
+ m->NATMcastRecvskt = mDNSPlatformUDPSocket(NATPMPAnnouncementPort);
if (!m->NATMcastRecvskt)
{
if (needLog)
@@ -5047,7 +5068,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
mDNSlocal mDNSs32 CheckRecordUpdates(mDNS *m)
{
AuthRecord *rr;
- mDNSs32 nextevent = m->timenow + 0x3FFFFFFF;
+ mDNSs32 nextevent = m->timenow + FutureTime;
CheckGroupRecordUpdates(m);
@@ -5105,7 +5126,7 @@ mDNSexport void uDNS_Tasks(mDNS *const m)
mDNSs32 nexte;
DNSServer *d;
- m->NextuDNSEvent = m->timenow + 0x3FFFFFFF;
+ m->NextuDNSEvent = m->timenow + FutureTime;
nexte = CheckRecordUpdates(m);
if (m->NextuDNSEvent - nexte > 0)
@@ -5400,7 +5421,7 @@ mDNSexport void uDNS_SetupWABQueries(mDNS *const m)
// Make sure we have the search domains from the platform layer so that if we start the WAB
// queries below, we have the latest information.
mDNS_Lock(m);
- if (!mDNSPlatformSetDNSConfig(m, mDNSfalse, mDNStrue, mDNSNULL, mDNSNULL, mDNSNULL, mDNSfalse))
+ if (!mDNSPlatformSetDNSConfig(mDNSfalse, mDNStrue, mDNSNULL, mDNSNULL, mDNSNULL, mDNSfalse))
{
// If the configuration did not change, clear the flag so that we don't free the searchlist.
// We still have to start the domain enumeration queries as we may not have started them
@@ -5648,11 +5669,10 @@ mDNSexport void uDNS_StopWABQueries(mDNS *const m, int queryType)
uDNS_SetupWABQueries(m);
}
-mDNSexport domainname *uDNS_GetNextSearchDomain(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal)
+mDNSexport domainname *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal)
{
SearchListElem *p = SearchList;
int count = *searchIndex;
- (void) m; // unused
if (count < 0) { LogMsg("uDNS_GetNextSearchDomain: count %d less than zero", count); return mDNSNULL; }
@@ -5775,10 +5795,15 @@ struct CompileTimeAssertionChecks_uDNS
#pragma mark - DNS Push Notification functions
#endif
+#ifdef DNS_PUSH_ENABLED
mDNSlocal tcpInfo_t * GetTCPConnectionToPushServer(mDNS *m, DNSQuestion *q)
{
+ DNSPushNotificationZone *zone;
+ DNSPushNotificationServer *server;
+ DNSPushNotificationZone *newZone;
+ DNSPushNotificationServer *newServer;
+
// If we already have a question for this zone and if the server is the same, reuse it
- DNSPushNotificationZone *zone = mDNSNULL;
for (zone = m->DNSPushZones; zone != mDNSNULL; zone = zone->next)
{
if (SameDomainName(&q->nta->ChildName, &zone->zoneName))
@@ -5797,12 +5822,11 @@ mDNSlocal tcpInfo_t * GetTCPConnectionToPushServer(mDNS *m, DNSQuestion *q)
}
// If we have a connection to this server but it is for a differnt zone, create a new zone entry and reuse the connection
- DNSPushNotificationServer *server = mDNSNULL;
for (server = m->DNSPushServers; server != mDNSNULL; server = server->next)
{
if (mDNSSameAddress(&q->dnsPushServerAddr, &server->serverAddr))
{
- DNSPushNotificationZone *newZone = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationZone));
+ newZone = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationZone));
newZone->numberOfQuestions = 1;
newZone->zoneName = q->nta->ChildName;
newZone->servers = server;
@@ -5817,8 +5841,8 @@ mDNSlocal tcpInfo_t * GetTCPConnectionToPushServer(mDNS *m, DNSQuestion *q)
}
// If we do not have any existing connections, create a new connection
- DNSPushNotificationServer *newServer = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationServer));
- DNSPushNotificationZone *newZone = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationZone));
+ newServer = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationServer));
+ newZone = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationZone));
newServer->numberOfQuestions = 1;
newServer->serverAddr = q->dnsPushServerAddr;
@@ -5930,6 +5954,9 @@ mDNSlocal void reconcileDNSPushConnection(mDNS *m, DNSQuestion *q)
{
DNSPushNotificationZone *zone;
DNSPushNotificationServer *server;
+ DNSPushNotificationServer *nextServer;
+ DNSPushNotificationZone *nextZone;
+
// Update the counts
for (zone = m->DNSPushZones; zone != mDNSNULL; zone = zone->next)
{
@@ -5946,7 +5973,7 @@ mDNSlocal void reconcileDNSPushConnection(mDNS *m, DNSQuestion *q)
// Now prune the lists
server = m->DNSPushServers;
- DNSPushNotificationServer *nextServer = mDNSNULL;
+ nextServer = mDNSNULL;
while(server != mDNSNULL)
{
nextServer = server->next;
@@ -5962,7 +5989,7 @@ mDNSlocal void reconcileDNSPushConnection(mDNS *m, DNSQuestion *q)
}
zone = m->DNSPushZones;
- DNSPushNotificationZone *nextZone = mDNSNULL;
+ nextZone = mDNSNULL;
while(zone != mDNSNULL)
{
nextZone = zone->next;
@@ -5994,6 +6021,7 @@ mDNSexport void UnSubscribeToDNSPushNotificationServer(mDNS *m, DNSQuestion *q)
reconcileDNSPushConnection(m, q);
}
+#endif // DNS_PUSH_ENABLED
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#endif
@@ -6119,9 +6147,8 @@ mDNSexport mStatus mDNS_SetSecretForDomain(mDNS *m, DomainAuthInfo *info, const
return mStatus_UnsupportedErr;
}
-mDNSexport domainname *uDNS_GetNextSearchDomain(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal)
+mDNSexport domainname *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal)
{
- (void) m;
(void) InterfaceID;
(void) searchIndex;
(void) ignoreDotLocal;
@@ -6154,8 +6181,8 @@ mDNSexport mStatus mDNS_StopNATOperation(mDNS *const m, NATTraversalInfo *traver
}
mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSs32 serviceID, const mDNSAddr *addr,
- const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSu16 resGroupID, mDNSBool reqA,
- mDNSBool reqAAAA, mDNSBool reqDO)
+ const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSu16 resGroupID,
+ mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO)
{
(void) m;
(void) d;
@@ -6166,6 +6193,7 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
(void) scoped;
(void) timeout;
(void) cellIntf;
+ (void) isExpensive;
(void) resGroupID;
(void) reqA;
(void) reqAAAA;
diff --git a/mDNSResponder/mDNSCore/uDNS.h b/mDNSResponder/mDNSCore/uDNS.h
index 910449f1..27b7acee 100755
--- a/mDNSResponder/mDNSCore/uDNS.h
+++ b/mDNSResponder/mDNSCore/uDNS.h
@@ -128,7 +128,7 @@ extern mStatus uDNS_SetupDNSConfig(mDNS *const m);
extern void uDNS_SetupWABQueries(mDNS *const m);
extern void uDNS_StartWABQueries(mDNS *const m, int queryType);
extern void uDNS_StopWABQueries(mDNS *const m, int queryType);
-extern domainname *uDNS_GetNextSearchDomain(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal);
+extern domainname *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal);
typedef enum
{