summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2020-01-07 15:42:59 +0200
committerToomas Soome <tsoome@me.com>2020-02-20 22:29:32 +0200
commit3b436d06bb95fd180ef7416b2b1b9972e2f2a513 (patch)
tree77190298b1f22f87516f5cfe89e14faad8fac20e
parent6d2858e77c6082a751ff9e66da7408d885792785 (diff)
downloadillumos-joyent-3b436d06bb95fd180ef7416b2b1b9972e2f2a513.tar.gz
12168 mDNSResponder update to mDNSResponder-878.260.1
Reviewed by: Ken Mays <kmays2000@gmail.com> Approved by: Robert Mustacchi <rm@fingolfin.org>
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/Makefile2
-rw-r--r--usr/src/contrib/mDNSResponder/Clients/dns-sd.c119
-rw-r--r--usr/src/contrib/mDNSResponder/README1
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.c374
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.h11
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/DNSDigest.c1
-rwxr-xr-xusr/src/contrib/mDNSResponder/mDNSCore/mDNS.c557
-rwxr-xr-xusr/src/contrib/mDNSResponder/mDNSCore/mDNSDebug.h10
-rwxr-xr-xusr/src/contrib/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h81
-rwxr-xr-xusr/src/contrib/mDNSResponder/mDNSCore/uDNS.c123
-rwxr-xr-xusr/src/contrib/mDNSResponder/mDNSCore/uDNS.h2
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSPosix/PosixDaemon.c2
-rwxr-xr-xusr/src/contrib/mDNSResponder/mDNSPosix/mDNSPosix.c31
-rwxr-xr-xusr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.c65
-rwxr-xr-xusr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.h8
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/PlatformCommon.c7
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/dns_sd.h62
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_private.h10
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientlib.c16
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientstub.c57
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/mDNSDebug.c3
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/uds_daemon.c116
22 files changed, 1099 insertions, 559 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/Makefile b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/Makefile
index 5424242b0d..80ab750e70 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/Makefile
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/Makefile
@@ -40,7 +40,7 @@ MDNSFLAGS= -DNOT_HAVE_SA_LEN \
-D_XPG4_2 -D__EXTENSIONS__ -DHAVE_BROKEN_RECVIF_NAME \
-DHAVE_IPV6=1 -Dasm=__asm -DMDNSD_NOROOT \
-DPID_FILE=\"\" -DMDNSD_USER=\"noaccess\" \
- -DmDNSResponderVersion=878.1.1
+ -DmDNSResponderVersion=878.260.1
include ../../../Makefile.cmd
diff --git a/usr/src/contrib/mDNSResponder/Clients/dns-sd.c b/usr/src/contrib/mDNSResponder/Clients/dns-sd.c
index f99482be04..b9fe853ce8 100644
--- a/usr/src/contrib/mDNSResponder/Clients/dns-sd.c
+++ b/usr/src/contrib/mDNSResponder/Clients/dns-sd.c
@@ -174,10 +174,6 @@ static const char kFilePathSep = '/';
#include "../mDNSShared/dnssd_clientstub.c"
#endif
-#if _DNS_SD_LIBDISPATCH
-#include <dispatch/private.h>
-#endif
-
//*************************************************************************************************************
// Globals
@@ -416,46 +412,36 @@ static unsigned int keytag(unsigned char *key, unsigned int keysize)
return ac & 0xFFFF;
}
-static void base64Encode(char *buffer, int buflen, void *rdata, unsigned int rdlen)
+// Base 64 encoding according to <https://tools.ietf.org/html/rfc4648#section-4>.
+#define kBase64EncodingTable "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+
+static void base64Encode(char *buffer, size_t buflen, void *rdata, size_t rdlen)
{
-#if _DNS_SD_LIBDISPATCH
- const void *result = NULL;
- size_t size;
- dispatch_data_t src_data = NULL, dest_data = NULL, null_str = NULL, data = NULL, map = NULL;
-
- src_data = dispatch_data_create(rdata, rdlen, dispatch_get_global_queue(0, 0), ^{});
- if (!src_data)
- goto done;
-
- dest_data = dispatch_data_create_with_transform(src_data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE64);
- if (!dest_data)
- goto done;
-
- null_str = dispatch_data_create("", 1, dispatch_get_global_queue(0, 0), ^{});
- if (!null_str)
- goto done;
-
- data = dispatch_data_create_concat(dest_data, null_str);
- if (!data)
- goto done;
-
- map = dispatch_data_create_map(data, &result, &size);
- if (!map)
- goto done;
-
- snprintf(buffer, buflen, " %s", (char *)result);
-
-done:
- if (src_data) dispatch_release(src_data);
- if (dest_data) dispatch_release(dest_data);
- if (data) dispatch_release(data);
- if (null_str) dispatch_release(null_str);
- if (map) dispatch_release(map);
- return;
-#else //_DNS_SD_LIBDISPATCH
- snprintf(buffer, buflen, " %s", ".");
- return;
-#endif //_DNS_SD_LIBDISPATCH
+ const uint8_t *src = (const uint8_t *)rdata;
+ const uint8_t *const end = &src[rdlen];
+ char *dst = buffer;
+ const char *lim;
+
+ if (buflen == 0) return;
+ lim = &buffer[buflen - 1];
+ while ((src < end) && (dst < lim))
+ {
+ uint32_t i;
+ const size_t rem = (size_t)(end - src);
+
+ // Form a 24-bit input group. If less than 24 bits remain, pad with zero bits.
+ if ( rem >= 3) i = (src[0] << 16) | (src[1] << 8) | src[2]; // 24 bits are equal to 4 6-bit groups.
+ else if (rem == 2) i = (src[0] << 16) | (src[1] << 8); // 16 bits are treated as 3 6-bit groups + 1 pad
+ else i = src[0] << 16; // 8 bits are treated as 2 6-bit groups + 2 pads
+
+ // Encode each 6-bit group.
+ *dst++ = kBase64EncodingTable[(i >> 18) & 0x3F];
+ if (dst < lim) *dst++ = kBase64EncodingTable[(i >> 12) & 0x3F];
+ if (dst < lim) *dst++ = (rem >= 2) ? kBase64EncodingTable[(i >> 6) & 0x3F] : '=';
+ if (dst < lim) *dst++ = (rem >= 3) ? kBase64EncodingTable[ i & 0x3F] : '=';
+ src += (rem > 3) ? 3 : rem;
+ }
+ *dst = '\0';
}
static DNSServiceProtocol GetProtocol(const char *s)
@@ -924,10 +910,10 @@ static int snprintd(char *p, int max, const unsigned char **rd)
return(p-buf);
}
-static void ParseDNSSECRecords(uint16_t rrtype, char *rdb, char *p, unsigned const char *rd, uint16_t rdlen)
+static void ParseDNSSECRecords(uint16_t rrtype, char *rdb, size_t rdb_size, unsigned const char *rd, uint16_t rdlen)
{
- int rdb_size = 1000;
- switch (rrtype)
+ char *p = rdb;
+ switch (rrtype)
{
case kDNSServiceType_DS:
{
@@ -945,7 +931,7 @@ static void ParseDNSSECRecords(uint16_t rrtype, char *rdb, char *p, unsigned con
case kDNSServiceType_DNSKEY:
{
rdataDNSKey *rrkey = (rdataDNSKey *)rd;
- p += snprintf(p, rdb + rdb_size - p, "%d %d %d %u", swap16(rrkey->flags), rrkey->proto,
+ p += snprintf(p, rdb + rdb_size - p, "%d %d %d %u ", swap16(rrkey->flags), rrkey->proto,
rrkey->alg, (unsigned int)keytag((unsigned char *)rrkey, rdlen));
base64Encode(p, rdb + rdb_size - p, (unsigned char *)(rd + DNSKEY_FIXED_SIZE), rdlen - DNSKEY_FIXED_SIZE);
break;
@@ -1026,7 +1012,12 @@ static void ParseDNSSECRecords(uint16_t rrtype, char *rdb, char *p, unsigned con
k = p;
p += snprintd(p, rdb + rdb_size - p, &q);
len = p - k + 1;
-
+
+ if ((&rdb[rdb_size] - p) >= 2)
+ {
+ *p++ = ' ';
+ *p = '\0';
+ }
base64Encode(p, rdb + rdb_size - p, (unsigned char *)(rd + len + RRSIG_FIXED_SIZE), rdlen - (len + RRSIG_FIXED_SIZE));
break;
}
@@ -1056,9 +1047,9 @@ static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags,
if (num_printed++ == 0)
{
if (operation == 'D')
- printf("Timestamp A/R if %-30s%-6s%-7s%-18s Rdata\n", "Name", "Type", "Class", "DNSSECStatus");
+ printf("Timestamp A/R if %-30s%-6s%-7s%-18s Rdata\n", "Name", "Type", "Class", "DNSSECStatus");
else
- printf("Timestamp A/R Flags if %-30s%-6s%-7s Rdata\n", "Name", "Type", "Class");
+ printf("Timestamp A/R Flags if %-30s%-6s%-7s Rdata\n", "Name", "Type", "Class");
}
printtimestamp();
@@ -1115,7 +1106,7 @@ static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags,
case kDNSServiceType_DNSKEY:
case kDNSServiceType_NSEC:
case kDNSServiceType_RRSIG:
- ParseDNSSECRecords(rrtype, rdb, p, rd, rdlen);
+ ParseDNSSECRecords(rrtype, rdb, sizeof(rdb), rd, rdlen);
break;
default:
@@ -1143,7 +1134,7 @@ static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags,
if (operation == 'D')
printf("%s%3d %-30s%-6s%-7s%-18s %s", op, ifIndex, fullname, rr_type, rr_class, dnssec_status, rdb);
else
- printf("%s%6X%3d %-30s%-7s%-6s %s", op, flags, ifIndex, fullname, rr_type, rr_class, rdb);
+ printf("%s%9X%3d %-30s%-7s%-6s %s", op, flags, ifIndex, fullname, rr_type, rr_class, rdb);
if (unknowntype)
{
while (rd < end)
@@ -1208,7 +1199,7 @@ static void DNSSD_API addrinfo_reply(DNSServiceRef sdref, const DNSServiceFlags
if (operation == 'g')
printf("Timestamp A/R if %-25s %-44s %-18s\n", "Hostname", "Address", "DNSSECStatus");
else
- printf("Timestamp A/R Flags if %-38s %-44s %s\n", "Hostname", "Address", "TTL");
+ printf("Timestamp A/R Flags if %-38s %-44s %s\n", "Hostname", "Address", "TTL");
}
printtimestamp();
@@ -1248,7 +1239,7 @@ static void DNSSD_API addrinfo_reply(DNSServiceRef sdref, const DNSServiceFlags
if (operation == 'g')
printf("%s%3d %-25s %-44s %-18s", op, interfaceIndex, hostname, addr, dnssec_status);
else
- printf("%s%6X%3d %-38s %-44s %d", op, flags, interfaceIndex, hostname, addr, ttl);
+ printf("%s%9X%3d %-38s %-44s %d", op, flags, interfaceIndex, hostname, addr, ttl);
if (errorCode)
{
if (errorCode == kDNSServiceErr_NoSuchRecord)
@@ -1513,12 +1504,6 @@ static int API_string_limit_test()
return 0;
}
-// local prototypes for routines that don't have prototypes in dns_sd.h
-#if APPLE_OSX_mDNSResponder
-DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain);
-DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *sdRef, int32_t pid, uuid_t uuid);
-#endif
-
static int API_NULL_input_test()
{
printf("Running basic API input range tests with various pointer parameters set to NULL:\n");
@@ -1915,7 +1900,15 @@ int main(int argc, char **argv)
argv++;
opinterface = kDNSServiceInterfaceIndexBLE;
}
-
+
+ if (argc > 1 && !strcasecmp(argv[1], "-allowexpired"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsAllowExpiredAnswers;
+ printf("Setting kDNSServiceFlagsAllowExpiredAnswers\n");
+ }
+
if (argc > 1 && !strcasecmp(argv[1], "-includep2p"))
{
argc--;
@@ -2288,7 +2281,11 @@ Fail:
// NOT static -- otherwise the compiler may optimize it out
// The "@(#) " pattern is a special prefix the "what" command looks for
+#ifndef MDNS_VERSIONSTR_NODTS
+const char VersionString_SCCS[] = "@(#) dns-sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
+#else
const char VersionString_SCCS[] = "@(#) dns-sd " STRINGIFY(mDNSResponderVersion);
+#endif
#if _BUILDING_XCODE_PROJECT_
// If the process crashes, then this string will be magically included in the automatically-generated crash log
diff --git a/usr/src/contrib/mDNSResponder/README b/usr/src/contrib/mDNSResponder/README
index ea5d4d4740..73c8188fba 100644
--- a/usr/src/contrib/mDNSResponder/README
+++ b/usr/src/contrib/mDNSResponder/README
@@ -24,6 +24,7 @@
The mdns vendor source repository is at https://github.com/illumos/mdns/.
+Updated from upstream version mDNSResponder-878.260.1
Updated from upstream version mDNSResponder-878.1.1
Updated from upstream version mDNSResponder-625.41.2
Updated from upstream version mDNSResponder-576.30.4
diff --git a/usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.c b/usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.c
index 323974cb45..35d4e2649c 100644
--- a/usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.c
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2018 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -2770,7 +2770,9 @@ mDNSexport const mDNSu8 *getDomainName(const DNSMessage *const msg, const mDNSu8
case 0x80: debugf("getDomainName: Illegal label length 0x%X in domain name %##s", len, name->c); return(mDNSNULL);
- case 0xC0: offset = (mDNSu16)((((mDNSu16)(len & 0x3F)) << 8) | *ptr++);
+ case 0xC0: if (ptr >= end)
+ { debugf("getDomainName: Malformed compression label (overruns packet end)"); return(mDNSNULL); }
+ offset = (mDNSu16)((((mDNSu16)(len & 0x3F)) << 8) | *ptr++);
if (!nextbyte) nextbyte = ptr; // Record where we got to before we started following pointers
ptr = (mDNSu8 *)msg + offset;
if (ptr < (mDNSu8*)msg || ptr >= end)
@@ -3335,7 +3337,7 @@ mDNSexport mDNSBool SetRData(const DNSMessage *const msg, const mDNSu8 *ptr, con
AssignDomainName(&name, (domainname *)ptr);
ptr += DomainNameLength(&name);
}
- if (!ptr)
+ if (!ptr || ptr >= end)
{
LogInfo("SetRData: Malformed name for TSIG/TKEY type %d", rr->resrec.rrtype);
goto fail;
@@ -3448,7 +3450,6 @@ mDNSexport const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage
rr->TimeRcvd = m ? m->timenow : 0;
rr->DelayDelivery = 0;
rr->NextRequiredQuery = m ? m->timenow : 0; // Will be updated to the real value when we call SetNextCacheCheckTimeForRecord()
- rr->LastUsed = m ? m->timenow : 0;
rr->CRActiveQuestion = mDNSNULL;
rr->UnansweredQueries = 0;
rr->LastUnansweredTime= 0;
@@ -3466,16 +3467,15 @@ mDNSexport const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage
rr->resrec.rrtype = (mDNSu16) ((mDNSu16)ptr[0] << 8 | ptr[1]);
rr->resrec.rrclass = (mDNSu16)(((mDNSu16)ptr[2] << 8 | ptr[3]) & kDNSClass_Mask);
rr->resrec.rroriginalttl = (mDNSu32) ((mDNSu32)ptr[4] << 24 | (mDNSu32)ptr[5] << 16 | (mDNSu32)ptr[6] << 8 | ptr[7]);
- if (rr->resrec.rroriginalttl > 0x70000000UL / mDNSPlatformOneSecond && (mDNSs32)rr->resrec.rroriginalttl != -1)
- rr->resrec.rroriginalttl = 0x70000000UL / mDNSPlatformOneSecond;
+ if (rr->resrec.rroriginalttl > mDNSMaximumTTLSeconds && (mDNSs32)rr->resrec.rroriginalttl != -1)
+ rr->resrec.rroriginalttl = mDNSMaximumTTLSeconds;
// Note: We don't have to adjust m->NextCacheCheck here -- this is just getting a record into memory for
// us to look at. If we decide to copy it into the cache, then we'll update m->NextCacheCheck accordingly.
pktrdlength = (mDNSu16)((mDNSu16)ptr[8] << 8 | ptr[9]);
// If mDNS record has cache-flush bit set, we mark it unique
- // For uDNS records, all are implicitly deemed unique (a single DNS server is always
- // authoritative for the entire RRSet), unless this is a truncated response
- if (ptr[2] & (kDNSClass_UniqueRRSet >> 8) || (!InterfaceID && !(msg->h.flags.b[0] & kDNSFlag0_TC)))
+ // For uDNS records, all are implicitly deemed unique (a single DNS server is always authoritative for the entire RRSet)
+ if (ptr[2] & (kDNSClass_UniqueRRSet >> 8) || !InterfaceID)
RecordType |= kDNSRecordTypePacketUniqueMask;
ptr += 10;
if (ptr + pktrdlength > end) { debugf("GetLargeResourceRecord: RDATA exceeds end of packet"); return(mDNSNULL); }
@@ -3629,25 +3629,6 @@ mDNSexport mDNSBool GetPktLease(mDNS *const m, const DNSMessage *const msg, cons
return mDNSfalse;
}
-mDNSlocal const mDNSu8 *DumpRecords(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end, int count, char *label)
-{
- int i;
- LogInfo("%2d %s", count, label);
- for (i = 0; i < count && ptr; i++)
- {
- // This puts a LargeCacheRecord on the stack instead of using the shared m->rec storage,
- // but since it's only used for debugging (and probably only on OS X, not on
- // embedded systems) putting a 9kB object on the stack isn't a big problem.
- LargeCacheRecord largecr;
- ptr = GetLargeResourceRecord(m, msg, ptr, end, mDNSInterface_Any, kDNSRecordTypePacketAns, &largecr);
- if (ptr)
- LogInfo("%2d TTL%8d %s", i, largecr.r.resrec.rroriginalttl, CRDisplayString(m, &largecr.r));
- }
- if (!ptr)
- LogInfo("DumpRecords: ERROR: Premature end of packet data");
- return(ptr);
-}
-
#define DNS_OP_Name(X) ( \
(X) == kDNSFlag0_OP_StdQuery ? "" : \
(X) == kDNSFlag0_OP_Iquery ? "Iquery " : \
@@ -3671,52 +3652,198 @@ mDNSlocal const mDNSu8 *DumpRecords(mDNS *const m, const DNSMessage *const msg,
(X) == kDNSFlag1_RC_NotAuth ? "NotAuth" : \
(X) == kDNSFlag1_RC_NotZone ? "NotZone" : "??" )
-// Note: DumpPacket expects the packet header fields in host byte order, not network byte order
-mDNSexport 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)
+mDNSlocal void mDNS_snprintf_add(char **ptr, const char *lim, const char *fmt, ...)
{
- mDNSBool IsUpdate = ((msg->h.flags.b[0] & kDNSFlag0_OP_Mask) == kDNSFlag0_OP_Update);
- const mDNSu8 *ptr = msg->data;
- int i;
- DNSQuestion q;
- char tbuffer[64], sbuffer[64], dbuffer[64] = "";
- if (!status) tbuffer[mDNS_snprintf(tbuffer, sizeof(tbuffer), sent ? "Sent" : "Received" )] = 0;
- else tbuffer[mDNS_snprintf(tbuffer, sizeof(tbuffer), "ERROR %d %sing", status, sent ? "Send" : "Receive")] = 0;
- if (sent) sbuffer[mDNS_snprintf(sbuffer, sizeof(sbuffer), "port " )] = 0;
- else sbuffer[mDNS_snprintf(sbuffer, sizeof(sbuffer), "%#a:", srcaddr)] = 0;
- if (dstaddr || !mDNSIPPortIsZero(dstport))
- dbuffer[mDNS_snprintf(dbuffer, sizeof(dbuffer), " to %#a:%d", dstaddr, mDNSVal16(dstport))] = 0;
-
- LogInfo("-- %s %s DNS %s%s (flags %02X%02X) RCODE: %s (%d) %s%s%s%s%s%sID: %d %d bytes from %s%d%s%s --",
- tbuffer, transport,
+ va_list args;
+ mDNSu32 buflen, n;
+ char *const dst = *ptr;
+
+ buflen = (mDNSu32)(lim - dst);
+ if (buflen > 0)
+ {
+ va_start(args, fmt);
+ n = mDNS_vsnprintf(dst, buflen, fmt, args);
+ va_end(args);
+ *ptr = dst + n;
+ }
+}
+
+#define DNSTypeString(X) (((X) == kDNSType_A) ? "A" : DNSTypeName(X))
+
+#define ReadField16(PTR) ((mDNSu16)((((mDNSu16)((mDNSu8 *)(PTR))[0]) << 8) | ((mDNSu16)((mDNSu8 *)(PTR))[1])))
+#define ReadField32(PTR) \
+ ((mDNSu32)( \
+ (((mDNSu32)((mDNSu8 *)(PTR))[0]) << 24) | \
+ (((mDNSu32)((mDNSu8 *)(PTR))[1]) << 16) | \
+ (((mDNSu32)((mDNSu8 *)(PTR))[2]) << 8) | \
+ ((mDNSu32)((mDNSu8 *)(PTR))[3])))
+
+mDNSlocal void DNSMessageDump(const DNSMessage *const msg, const mDNSu8 *const end, char *buffer, mDNSu32 buflen)
+{
+ domainname *name;
+ const mDNSu8 *ptr;
+ domainname nameStorage[2];
+ char *dst = buffer;
+ const char *const lim = &buffer[buflen];
+ mDNSu32 i;
+ const mDNSu32 rrcount = msg->h.numAnswers + msg->h.numAuthorities + msg->h.numAdditionals;
+
+ mDNS_snprintf_add(&dst, lim, "DNS %s%s (%lu) (flags %02X%02X) RCODE: %s (%d)%s%s%s%s%s%s ID: %u:",
DNS_OP_Name(msg->h.flags.b[0] & kDNSFlag0_OP_Mask),
- msg->h.flags.b[0] & kDNSFlag0_QR_Response ? "Response" : "Query",
+ (msg->h.flags.b[0] & kDNSFlag0_QR_Response) ? "Response" : "Query",
+ (unsigned long)(end - (const mDNSu8 *)msg),
msg->h.flags.b[0], msg->h.flags.b[1],
DNS_RC_Name(msg->h.flags.b[1] & kDNSFlag1_RC_Mask),
msg->h.flags.b[1] & kDNSFlag1_RC_Mask,
- msg->h.flags.b[0] & kDNSFlag0_AA ? "AA " : "",
- msg->h.flags.b[0] & kDNSFlag0_TC ? "TC " : "",
- msg->h.flags.b[0] & kDNSFlag0_RD ? "RD " : "",
- msg->h.flags.b[1] & kDNSFlag1_RA ? "RA " : "",
- msg->h.flags.b[1] & kDNSFlag1_AD ? "AD " : "",
- msg->h.flags.b[1] & kDNSFlag1_CD ? "CD " : "",
- mDNSVal16(msg->h.id),
- end - msg->data,
- sbuffer, mDNSVal16(srcport), dbuffer,
- (msg->h.flags.b[0] & kDNSFlag0_TC) ? " (truncated)" : ""
- );
-
- LogInfo("%2d %s", msg->h.numQuestions, IsUpdate ? "Zone" : "Questions");
- for (i = 0; i < msg->h.numQuestions && ptr; i++)
+ (msg->h.flags.b[0] & kDNSFlag0_AA) ? " AA" : "",
+ (msg->h.flags.b[0] & kDNSFlag0_TC) ? " TC" : "",
+ (msg->h.flags.b[0] & kDNSFlag0_RD) ? " RD" : "",
+ (msg->h.flags.b[1] & kDNSFlag1_RA) ? " RA" : "",
+ (msg->h.flags.b[1] & kDNSFlag1_AD) ? " AD" : "",
+ (msg->h.flags.b[1] & kDNSFlag1_CD) ? " CD" : "",
+ mDNSVal16(msg->h.id));
+
+ name = mDNSNULL;
+ ptr = msg->data;
+ for (i = 0; i < msg->h.numQuestions; i++)
+ {
+ mDNSu16 qtype, qclass;
+
+ name = &nameStorage[0];
+ ptr = getDomainName(msg, ptr, end, name);
+ if (!ptr) goto exit;
+
+ if ((end - ptr) < 4) goto exit;
+ qtype = ReadField16(&ptr[0]);
+ qclass = ReadField16(&ptr[2]);
+ ptr += 4;
+
+ mDNS_snprintf_add(&dst, lim, " %##s %s", name->c, DNSTypeString(qtype));
+ if (qclass != kDNSClass_IN) mDNS_snprintf_add(&dst, lim, "/%u", qclass);
+ mDNS_snprintf_add(&dst, lim, "?");
+ }
+
+ mDNS_snprintf_add(&dst, lim, " %u/%u/%u", msg->h.numAnswers, msg->h.numAuthorities, msg->h.numAdditionals);
+ for (i = 0; i < rrcount; i++)
{
- ptr = getQuestion(msg, ptr, end, mDNSInterface_Any, &q);
- if (ptr) LogInfo("%2d %##s %s", i, q.qname.c, DNSTypeName(q.qtype));
+ mDNSu16 rrtype, rrclass, rdlength;
+ mDNSu32 ttl;
+ int handled;
+ const mDNSu8 *rdata;
+ const domainname *const previousName = name;
+
+ name = &nameStorage[(name == &nameStorage[0]) ? 1 : 0];
+ ptr = getDomainName(msg, ptr, end, name);
+ if (!ptr) goto exit;
+
+ if ((end - ptr) < 10) goto exit;
+ rrtype = ReadField16(&ptr[0]);
+ rrclass = ReadField16(&ptr[2]);
+ ttl = ReadField32(&ptr[4]);
+ rdlength = ReadField16(&ptr[8]);
+ ptr += 10;
+
+ if ((end - ptr) < rdlength) goto exit;
+ rdata = ptr;
+
+ if (i > 0) mDNS_snprintf_add(&dst, lim, ",");
+ if (!previousName || !SameDomainName(name, previousName)) mDNS_snprintf_add(&dst, lim, " %##s", name);
+
+ mDNS_snprintf_add(&dst, lim, " %s", DNSTypeString(rrtype));
+ if (rrclass != kDNSClass_IN) mDNS_snprintf_add(&dst, lim, "/%u", rrclass);
+ mDNS_snprintf_add(&dst, lim, " ");
+
+ handled = mDNSfalse;
+ switch (rrtype)
+ {
+ case kDNSType_A:
+ if (rdlength == 4)
+ {
+ mDNS_snprintf_add(&dst, lim, "%.4a", rdata);
+ handled = mDNStrue;
+ }
+ break;
+
+ case kDNSType_AAAA:
+ if (rdlength == 16)
+ {
+ mDNS_snprintf_add(&dst, lim, "%.16a", rdata);
+ handled = mDNStrue;
+ }
+ break;
+
+ case kDNSType_CNAME:
+ ptr = getDomainName(msg, rdata, end, name);
+ if (!ptr) goto exit;
+
+ mDNS_snprintf_add(&dst, lim, "%##s", name);
+ handled = mDNStrue;
+ break;
+
+ case kDNSType_SOA:
+ {
+ mDNSu32 serial, refresh, retry, expire, minimum;
+ domainname *const mname = &nameStorage[0];
+ domainname *const rname = &nameStorage[1];
+ name = mDNSNULL;
+
+ ptr = getDomainName(msg, rdata, end, mname);
+ if (!ptr) goto exit;
+
+ ptr = getDomainName(msg, ptr, end, rname);
+ if (!ptr) goto exit;
+
+ if ((end - ptr) < 20) goto exit;
+ serial = ReadField32(&ptr[0]);
+ refresh = ReadField32(&ptr[4]);
+ retry = ReadField32(&ptr[8]);
+ expire = ReadField32(&ptr[12]);
+ minimum = ReadField32(&ptr[16]);
+
+ mDNS_snprintf_add(&dst, lim, "%##s %##s %lu %lu %lu %lu %lu", mname, rname, (unsigned long)serial,
+ (unsigned long)refresh, (unsigned long)retry, (unsigned long)expire, (unsigned long)minimum);
+
+ handled = mDNStrue;
+ break;
+ }
+
+ default:
+ break;
+ }
+ if (!handled) mDNS_snprintf_add(&dst, lim, "RDATA[%u]: %.*H", rdlength, rdlength, rdata);
+ mDNS_snprintf_add(&dst, lim, " (%lu)", (unsigned long)ttl);
+ ptr = rdata + rdlength;
}
- ptr = DumpRecords(m, msg, ptr, end, msg->h.numAnswers, IsUpdate ? "Prerequisites" : "Answers");
- ptr = DumpRecords(m, msg, ptr, end, msg->h.numAuthorities, IsUpdate ? "Updates" : "Authorities");
- DumpRecords(m, msg, ptr, end, msg->h.numAdditionals, "Additionals");
- LogInfo("--------------");
+
+exit:
+ return;
+}
+
+// Note: DumpPacket expects the packet header fields in host byte order, not network byte order
+mDNSexport void DumpPacket(mStatus status, mDNSBool sent, char *transport,
+ const mDNSAddr *srcaddr, mDNSIPPort srcport,
+ const mDNSAddr *dstaddr, mDNSIPPort dstport, const DNSMessage *const msg, const mDNSu8 *const end)
+{
+ char buffer[512];
+ char *dst = buffer;
+ const char *const lim = &buffer[512];
+
+ buffer[0] = '\0';
+ if (!status) mDNS_snprintf_add(&dst, lim, sent ? "Sent" : "Received");
+ else mDNS_snprintf_add(&dst, lim, "ERROR %d %sing", status, sent ? "Send" : "Receiv");
+
+ mDNS_snprintf_add(&dst, lim, " %s DNS Message %u bytes from ", transport, (unsigned long)(end - (const mDNSu8 *)msg));
+
+ if (sent) mDNS_snprintf_add(&dst, lim, "port %d", mDNSVal16(srcport));
+ else mDNS_snprintf_add(&dst, lim, "%#a:%d", srcaddr, mDNSVal16(srcport));
+
+ if (dstaddr || !mDNSIPPortIsZero(dstport)) mDNS_snprintf_add(&dst, lim, " to %#a:%d", dstaddr, mDNSVal16(dstport));
+
+ LogInfo("%s", buffer);
+
+ buffer[0] = '\0';
+ DNSMessageDump(msg, end, buffer, (mDNSu32)sizeof(buffer));
+ LogInfo("%s", buffer);
}
// ***************************************************************************
@@ -3823,7 +3950,7 @@ mDNSexport mStatus mDNSSendDNSMessage(mDNS *const m, DNSMessage *const msg, mDNS
// Dump the packet with the HINFO and TSIG
if (mDNS_PacketLoggingEnabled && !mDNSOpaque16IsZero(msg->h.id))
- DumpPacket(m, status, mDNStrue, sock && (sock->flags & kTCPSocketFlags_UseTLS) ? "TLS" : sock ? "TCP" : "UDP", mDNSNULL, src ? src->port : MulticastDNSPort, dst, dstport, msg, end);
+ DumpPacket(status, mDNStrue, sock && (sock->flags & kTCPSocketFlags_UseTLS) ? "TLS" : sock ? "TCP" : "UDP", mDNSNULL, src ? src->port : MulticastDNSPort, dst, dstport, msg, end);
// put the number of additionals back the way it was
msg->h.numAdditionals = numAdditionals;
@@ -4052,6 +4179,9 @@ static const struct mDNSprintf_format
unsigned int precision;
} mDNSprintf_format_default = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+#define kHexDigitsLowercase "0123456789abcdef"
+#define kHexDigitsUppercase "0123456789ABCDEF";
+
mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, va_list arg)
{
mDNSu32 nwritten = 0;
@@ -4063,6 +4193,7 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
for (c = *fmt; c != 0; c = *++fmt)
{
unsigned long n;
+ int hexdump = mDNSfalse;
if (c != '%')
{
*sbuffer++ = (char)c;
@@ -4189,10 +4320,63 @@ decimal: if (!F.havePrecision)
a[0], a[1], a[2], a[3]); break;
case 6: i = mDNS_snprintf(mDNS_VACB, sizeof(mDNS_VACB), "%02X:%02X:%02X:%02X:%02X:%02X",
a[0], a[1], a[2], a[3], a[4], a[5]); break;
- case 16: i = mDNS_snprintf(mDNS_VACB, sizeof(mDNS_VACB),
- "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X",
- a[0x0], a[0x1], a[0x2], a[0x3], a[0x4], a[0x5], a[0x6], a[0x7],
- a[0x8], a[0x9], a[0xA], a[0xB], a[0xC], a[0xD], a[0xE], a[0xF]); break;
+ case 16: {
+ // Print IPv6 addresses according to RFC 5952, A Recommendation for IPv6 Address Text
+ // Representation. See <https://tools.ietf.org/html/rfc5952>.
+
+ int idx, runLen = 0, runStart = 0, maxRunLen = 0, maxRunStart = 0, maxRunEnd;
+
+ // Find the leftmost longest run of consecutive zero hextets.
+ for (idx = 0; idx < 8; ++idx)
+ {
+ const unsigned int hextet = (a[idx * 2] << 8) | a[(idx * 2) + 1];
+ if (hextet == 0)
+ {
+ if (runLen++ == 0) runStart = idx;
+ if (runLen > maxRunLen)
+ {
+ maxRunStart = runStart;
+ maxRunLen = runLen;
+ }
+ }
+ else
+ {
+ // If the number of remaining hextets is less than or equal to the length of the longest
+ // run so far, then we've found the leftmost longest run.
+ if ((8 - (idx + 1)) <= maxRunLen) break;
+ runLen = 0;
+ }
+ }
+
+ // Compress the leftmost longest run of two or more consecutive zero hextets as "::".
+ // For each reminaing hextet, suppress zeros leading up to the least-significant nibble, which
+ // is always written, even if it's zero. Because of this requirement, it's easier to write the
+ // IPv6 address in reverse. Also, write a colon separator before each hextet except for the
+ // first one.
+ s = mDNS_VACB_Lim;
+ maxRunEnd = (maxRunLen >= 2) ? (maxRunStart + maxRunLen - 1) : -1;
+ for (idx = 7; idx >= 0; --idx)
+ {
+ if (idx == maxRunEnd)
+ {
+ if (idx == 7) *--s = ':';
+ idx = maxRunStart;
+ *--s = ':';
+ }
+ else
+ {
+ unsigned int hextet = (a[idx * 2] << 8) | a[(idx * 2) + 1];
+ do {
+ *--s = kHexDigitsLowercase[hextet % 16];
+ hextet /= 16;
+ } while (hextet);
+ if (idx > 0) *--s = ':';
+ }
+ }
+ i = (unsigned int)(mDNS_VACB_Lim - s);
+ }
+ break;
+
default: i = mDNS_snprintf(mDNS_VACB, sizeof(mDNS_VACB), "%s", "<< ERROR: Must specify"
" address size (i.e. %.4a=IPv4, %.6a=Ethernet, %.16a=IPv6) >>"); break;
}
@@ -4203,9 +4387,9 @@ decimal: if (!F.havePrecision)
case 'p': F.havePrecision = F.lSize = 1;
F.precision = sizeof(void*) * 2; // 8 characters on 32-bit; 16 characters on 64-bit
/* FALLTHROUGH */
- case 'X': digits = "0123456789ABCDEF";
+ case 'X': digits = kHexDigitsUppercase;
goto hexadecimal;
- case 'x': digits = "0123456789abcdef";
+ case 'x': digits = kHexDigitsLowercase;
hexadecimal: if (F.lSize) n = va_arg(arg, unsigned long);
else n = va_arg(arg, unsigned int);
if (F.hSize) n = (unsigned short) n;
@@ -4288,6 +4472,12 @@ hexadecimal: if (F.lSize) n = va_arg(arg, unsigned long);
{ i = F.precision; while (i>0 && (s[i] & 0xC0) == 0x80) i--;}
break;
+ case 'H': {
+ s = va_arg(arg, char *);
+ hexdump = mDNStrue;
+ }
+ break;
+
case 'n': s = va_arg(arg, char *);
if (F.hSize) *(short *) s = (short)nwritten;
else if (F.lSize) *(long *) s = (long)nwritten;
@@ -4309,14 +4499,34 @@ hexadecimal: if (F.lSize) n = va_arg(arg, unsigned long);
if (++nwritten >= buflen) goto exit;
} while (i < --F.fieldWidth);
- // Make sure we don't truncate in the middle of a UTF-8 character.
- // Note: s[i] is the first eliminated character; i.e. the next character *after* the last character of the
- // allowed output. If s[i] is a UTF-8 continuation character, then we've cut a unicode character in half,
- // so back up 'i' until s[i] is no longer a UTF-8 continuation character. (if the input was proprly
- // formed, s[i] will now be the UTF-8 start character of the multi-byte character we just eliminated).
- if (i > buflen - nwritten)
- { i = buflen - nwritten; while (i>0 && (s[i] & 0xC0) == 0x80) i--;}
- for (j=0; j<i; j++) *sbuffer++ = *s++; // Write the converted result
+ if (hexdump)
+ {
+ char *dst = sbuffer;
+ const char *const lim = &sbuffer[buflen - nwritten];
+ if (F.havePrecision)
+ {
+ for (i = 0; (i < F.precision) && (dst < lim); i++)
+ {
+ const unsigned int b = (unsigned int) *s++;
+ if (i > 0) *dst++ = ' ';
+ if (dst < lim) *dst++ = kHexDigitsLowercase[(b >> 4) & 0xF];
+ if (dst < lim) *dst++ = kHexDigitsLowercase[ b & 0xF];
+ }
+ }
+ i = (unsigned int)(dst - sbuffer);
+ sbuffer = dst;
+ }
+ else
+ {
+ // Make sure we don't truncate in the middle of a UTF-8 character.
+ // Note: s[i] is the first eliminated character; i.e. the next character *after* the last character of the
+ // allowed output. If s[i] is a UTF-8 continuation character, then we've cut a unicode character in half,
+ // so back up 'i' until s[i] is no longer a UTF-8 continuation character. (if the input was proprly
+ // formed, s[i] will now be the UTF-8 start character of the multi-byte character we just eliminated).
+ if (i > buflen - nwritten)
+ { i = buflen - nwritten; while (i>0 && (s[i] & 0xC0) == 0x80) i--;}
+ for (j=0; j<i; j++) *sbuffer++ = *s++; // Write the converted result
+ }
nwritten += i;
if (nwritten >= buflen) goto exit;
diff --git a/usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.h b/usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.h
index 1e0e09abe1..6e468cdb81 100644
--- a/usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.h
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2018 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -110,6 +110,13 @@ extern mDNSu32 mDNSRandom(mDNSu32 max); // Returns pseudo-random result from
#define mDNSIsUpperCase(X) ((X) >= 'A' && (X) <= 'Z')
#define mDNSIsLowerCase(X) ((X) >= 'a' && (X) <= 'z')
#define mDNSIsLetter(X) (mDNSIsUpperCase(X) || mDNSIsLowerCase(X))
+
+// We believe we have adequate safeguards to protect against cache poisoning.
+// In the event that someone does find a workable cache poisoning attack, we want to limit the lifetime of the poisoned entry.
+// We set the maximum allowable TTL to one hour.
+// With the 25% correction factor to avoid the DNS Zeno's paradox bug, that gives us an actual maximum lifetime of 75 minutes.
+
+#define mDNSMaximumTTLSeconds (mDNSu32)3600
#define mDNSValidHostChar(X, notfirst, notlast) (mDNSIsLetter(X) || mDNSIsDigit(X) || ((notfirst) && (notlast) && (X) == '-') )
@@ -260,7 +267,7 @@ extern const mDNSu8 *LocateAdditionals(const DNSMessage *const msg, const mDNSu8
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 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,
+extern void DumpPacket(mStatus status, mDNSBool sent, char *transport,
const mDNSAddr *srcaddr, mDNSIPPort srcport,
const mDNSAddr *dstaddr, mDNSIPPort dstport, const DNSMessage *const msg, const mDNSu8 *const end);
extern mDNSBool RRAssertsNonexistence(const ResourceRecord *const rr, mDNSu16 type);
diff --git a/usr/src/contrib/mDNSResponder/mDNSCore/DNSDigest.c b/usr/src/contrib/mDNSResponder/mDNSCore/DNSDigest.c
index 0f8b32b082..6520ac6f6e 100644
--- a/usr/src/contrib/mDNSResponder/mDNSCore/DNSDigest.c
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/DNSDigest.c
@@ -1,6 +1,7 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2016 by Delphix. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/usr/src/contrib/mDNSResponder/mDNSCore/mDNS.c b/usr/src/contrib/mDNSResponder/mDNSCore/mDNS.c
index f51c22b287..0d94aae681 100755
--- a/usr/src/contrib/mDNSResponder/mDNSCore/mDNS.c
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/mDNS.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2018 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -83,7 +83,7 @@ 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 LocalRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
-mDNSlocal void mDNS_PurgeForQuestion(mDNS *const m, DNSQuestion *q);
+mDNSlocal void mDNS_PurgeBeforeResolve(mDNS *const m, DNSQuestion *q);
mDNSlocal void CheckForDNSSECRecords(mDNS *const m, DNSQuestion *q);
mDNSlocal void mDNS_SendKeepalives(mDNS *const m);
mDNSlocal void mDNS_ExtractKeepaliveInfo(AuthRecord *ar, mDNSu32 *timeout, mDNSAddr *laddr, mDNSAddr *raddr, mDNSEthAddr *eth,
@@ -548,6 +548,7 @@ mDNSexport void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, Re
// because mDNS_StartQuery_internal re-initializes CNAMEReferrals to zero
q->CNAMEReferrals = c;
#if AWD_METRICS
+ metrics.expiredAnswerState = q->metrics.expiredAnswerState; // We want the newly initialized state for this value
q->metrics = metrics;
#endif
if (sock)
@@ -785,6 +786,7 @@ mDNSlocal void AnswerAllLocalQuestionsWithLocalAuthRecord(mDNS *const m, AuthRec
#define GoodbyeCount ((mDNSu8)3)
#define WakeupCount ((mDNSu8)18)
#define MAX_PROBE_RESTARTS ((mDNSu8)20)
+#define MAX_GHOST_TIME ((mDNSs32)((60*60*24*7)*mDNSPlatformOneSecond)) // One week
// Number of wakeups we send if WakeOnResolve is set in the question
#define InitialWakeOnResolveCount ((mDNSu8)3)
@@ -2176,7 +2178,7 @@ mDNSexport void CompleteDeregistration(mDNS *const m, AuthRecord *rr)
rr->resrec.RecordType = kDNSRecordTypeShared;
rr->RequireGoodbye = mDNSfalse;
rr->WakeUp.HMAC = zeroEthAddr;
- if (rr->AnsweredLocalQ) { AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse); rr->AnsweredLocalQ = mDNSfalse; }
+ if (rr->AnsweredLocalQ) { AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, QC_rmv); rr->AnsweredLocalQ = mDNSfalse; }
mDNS_Deregister_internal(m, rr, mDNS_Dereg_normal); // Don't touch rr after this
}
@@ -2364,7 +2366,11 @@ mDNSlocal void SendNDP(mDNS *const m, const mDNSu8 op, const mDNSu8 flags, const
// *ptr++ = tpa->b[0xF];
// 0x06 Source address (Note: Since we don't currently set the BIOCSHDRCMPLT option, BPF will fill in the real interface address for us)
- for (i=0; i<6; i++) *ptr++ = (tha ? *tha : intf->MAC).b[i];
+ for (i=0; i<6; i++)
+ if (tha)
+ *ptr++ = tha->b[i];
+ else
+ *ptr++ = intf->MAC.b[i];
// 0x0C IPv6 Ethertype (0x86DD)
*ptr++ = 0x86; *ptr++ = 0xDD;
@@ -2401,7 +2407,11 @@ mDNSlocal void SendNDP(mDNS *const m, const mDNSu8 op, const mDNSu8 flags, const
{
*ptr++ = NDP_SrcLL; // Option Type 1 == Source Link-layer Address
*ptr++ = 0x01; // Option length 1 (in units of 8 octets)
- for (i=0; i<6; i++) *ptr++ = (tha ? *tha : intf->MAC).b[i];
+ for (i=0; i<6; i++)
+ if (tha)
+ *ptr++ = tha->b[i];
+ else
+ *ptr++ = intf->MAC.b[i];
}
}
else // Neighbor Advertisement. The NDP "target" is the address we're giving information about.
@@ -2411,7 +2421,11 @@ mDNSlocal void SendNDP(mDNS *const m, const mDNSu8 op, const mDNSu8 flags, const
// 0x4E Target Link-layer Address
*ptr++ = NDP_TgtLL; // Option Type 2 == Target Link-layer Address
*ptr++ = 0x01; // Option length 1 (in units of 8 octets)
- for (i=0; i<6; i++) *ptr++ = (tha ? *tha : intf->MAC).b[i];
+ for (i=0; i<6; i++)
+ if (tha)
+ *ptr++ = tha->b[i];
+ else
+ *ptr++ = intf->MAC.b[i];
}
// 0x4E or 0x56 Total NDP Packet length 78 or 86 bytes
@@ -3220,21 +3234,25 @@ mDNSlocal mDNSBool BuildQuestion(mDNS *const m, const NetworkInterfaceInfo *intf
// Depth 3: PTR "_services._dns-sd._udp.local." refers to "_example._tcp.local."; may be stale
// Currently depths 4 and 5 are not expected to occur; if we did get to depth 5 we'd reconfim any records we
// found referring to the given name, but not recursively descend any further reconfirm *their* antecedents.
-mDNSlocal void ReconfirmAntecedents(mDNS *const m, const domainname *const name, const mDNSu32 namehash, const int depth)
+mDNSlocal void ReconfirmAntecedents(mDNS *const m, const domainname *const name, const mDNSu32 namehash, const mDNSInterfaceID InterfaceID, const int depth)
{
mDNSu32 slot;
- CacheGroup *cg;
+ const CacheGroup *cg;
CacheRecord *cr;
debugf("ReconfirmAntecedents (depth=%d) for %##s", depth, name->c);
+ if (!InterfaceID) return; // mDNS records have a non-zero InterfaceID. If InterfaceID is 0, then there's nothing to do.
FORALL_CACHERECORDS(slot, cg, cr)
{
- domainname *crtarget = GetRRDomainNameTarget(&cr->resrec);
- if (crtarget && cr->resrec.rdatahash == namehash && SameDomainName(crtarget, name))
+ const domainname *crtarget;
+ if (cr->resrec.InterfaceID != InterfaceID) continue; // Skip non-mDNS records and mDNS records from other interfaces.
+ if (cr->resrec.rdatahash != namehash) continue; // Skip records whose rdata hash doesn't match the name hash.
+ crtarget = GetRRDomainNameTarget(&cr->resrec);
+ if (crtarget && SameDomainName(crtarget, name))
{
- LogInfo("ReconfirmAntecedents: Reconfirming (depth=%d) %s", depth, CRDisplayString(m, cr));
+ LogInfo("ReconfirmAntecedents: Reconfirming (depth=%d, InterfaceID=%p) %s", depth, InterfaceID, CRDisplayString(m, cr));
mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForNoAnswer);
if (depth < 5)
- ReconfirmAntecedents(m, cr->resrec.name, cr->resrec.namehash, depth+1);
+ ReconfirmAntecedents(m, cr->resrec.name, cr->resrec.namehash, InterfaceID, depth+1);
}
}
}
@@ -3612,7 +3630,8 @@ mDNSlocal void SendQueries(mDNS *const m)
{
q->ThisQInterval = MaxQuestionInterval;
}
- else if (q->CurrentAnswers == 0 && q->ThisQInterval == InitialQuestionInterval * QuestionIntervalStep3 && !q->RequestUnicast &&
+ else if (mDNSOpaque16IsZero(q->TargetQID) && q->InterfaceID &&
+ q->CurrentAnswers == 0 && q->ThisQInterval == InitialQuestionInterval * QuestionIntervalStep3 && !q->RequestUnicast &&
!(RRTypeIsAddressType(q->qtype) && CacheHasAddressTypeForName(m, &q->qname, q->qnamehash)))
{
// Generally don't need to log this.
@@ -3623,7 +3642,7 @@ mDNSlocal void SendQueries(mDNS *const m)
debugf("SendQueries: Zero current answers for %##s (%s); will reconfirm antecedents",
q->qname.c, DNSTypeName(q->qtype));
// Sending third query, and no answers yet; time to begin doubting the source
- ReconfirmAntecedents(m, &q->qname, q->qnamehash, 0);
+ ReconfirmAntecedents(m, &q->qname, q->qnamehash, q->InterfaceID, 0);
}
}
@@ -4107,8 +4126,9 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
DNSQuestion *const q = m->CurrentQuestion;
const mDNSBool followcname = FollowCNAME(q, &rr->resrec, AddRecord);
- verbosedebugf("AnswerCurrentQuestionWithResourceRecord:%4lu %s TTL %d %s",
- q->CurrentAnswers, AddRecord ? "Add" : "Rmv", rr->resrec.rroriginalttl, CRDisplayString(m, rr));
+ verbosedebugf("AnswerCurrentQuestionWithResourceRecord:%4lu %s (%s) TTL %d %s",
+ q->CurrentAnswers, AddRecord ? "Add" : "Rmv", MortalityDisplayString(rr->resrec.mortality),
+ rr->resrec.rroriginalttl, CRDisplayString(m, rr));
// When the response for the question was validated, the entire rrset was validated. If we deliver
// a RMV for a single record in the rrset, we invalidate the response. If we deliver another add
@@ -4149,7 +4169,11 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
if (!q->TimeoutQuestion || rr->resrec.RecordType != kDNSRecordTypePacketNegative || (m->timenow - q->StopTime < 0))
return;
}
-
+
+ // Set the record to immortal if appropriate
+ if (AddRecord == QC_add && Question_uDNS(q) && rr->resrec.RecordType != kDNSRecordTypePacketNegative &&
+ q->allowExpired != AllowExpired_None && rr->resrec.mortality == Mortality_Mortal ) rr->resrec.mortality = Mortality_Immortal; // Update a non-expired cache record to immortal if appropriate
+
#if AWD_METRICS
if ((AddRecord == QC_add) && Question_uDNS(q) && !followcname)
{
@@ -4170,12 +4194,12 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
responseLatencyMs = 0;
}
- MetricsUpdateUDNSQueryStats(queryName, q->qtype, &rr->resrec, q->metrics.querySendCount, responseLatencyMs, isForCellular);
+ MetricsUpdateDNSQueryStats(queryName, q->qtype, &rr->resrec, q->metrics.querySendCount, q->metrics.expiredAnswerState, responseLatencyMs, isForCellular);
q->metrics.answered = mDNStrue;
}
if (q->metrics.querySendCount > 0)
{
- MetricsUpdateUDNSResolveStats(queryName, &rr->resrec, isForCellular);
+ MetricsUpdateDNSResolveStats(queryName, &rr->resrec, isForCellular);
}
}
#endif
@@ -4183,8 +4207,7 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
// may be called twice, once when the record is received, and again when it's time to notify local clients.
// If any counters or similar are added here, care must be taken to ensure that they are not double-incremented by this.
- rr->LastUsed = m->timenow;
- if (AddRecord == QC_add && !q->DuplicateOf && rr->CRActiveQuestion != q)
+ if (AddRecord == QC_add && !q->DuplicateOf && rr->CRActiveQuestion != q && rr->resrec.mortality != Mortality_Ghost)
{
if (!rr->CRActiveQuestion) m->rrcache_active++; // If not previously active, increment rrcache_active count
debugf("AnswerCurrentQuestionWithResourceRecord: Updating CRActiveQuestion from %p to %p for cache record %s, CurrentAnswer %d",
@@ -4293,14 +4316,21 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
return;
}
- // Note: Proceed with caution here because client callback function is allowed to do anything,
- // including starting/stopping queries, registering/deregistering records, etc.
- //
- // If we get a CNAME back while we are validating the response (i.e., CNAME for DS, DNSKEY, RRSIG),
- // don't follow them. If it is a ValidationRequired question, wait for the CNAME to be validated
- // first before following it
- if ((m->CurrentQuestion == q) && followcname && !ValidatingQuestion(q))
- AnswerQuestionByFollowingCNAME(m, q, &rr->resrec);
+ if ((m->CurrentQuestion == q) && !ValidatingQuestion(q))
+ {
+ // If we get a CNAME back while we are validating the response (i.e., CNAME for DS, DNSKEY, RRSIG),
+ // don't follow them. If it is a ValidationRequired question, wait for the CNAME to be validated
+ // first before following it
+ if (followcname) AnswerQuestionByFollowingCNAME(m, q, &rr->resrec);
+
+ // If we are returning expired RRs, then remember the first expired qname we we can start the query again
+ if (rr->resrec.mortality == Mortality_Ghost && !q->firstExpiredQname.c[0] && (q->allowExpired == AllowExpired_AllowExpiredAnswers) && rr->resrec.RecordType != kDNSRecordTypePacketNegative)
+ {
+ debugf("AnswerCurrentQuestionWithResourceRecord: Keeping track of domain for expired RR %s for question %p", CRDisplayString(m,rr), q);
+ // Note: question->qname is already changed at this point if following a CNAME
+ AssignDomainName(&q->firstExpiredQname, rr->resrec.name); // Update firstExpiredQname
+ }
+ }
}
mDNSlocal void CacheRecordDeferredAdd(mDNS *const m, CacheRecord *rr)
@@ -4321,56 +4351,17 @@ mDNSlocal void CacheRecordDeferredAdd(mDNS *const m, CacheRecord *rr)
m->CurrentQuestion = mDNSNULL;
}
-mDNSlocal mDNSs32 CheckForSoonToExpireRecords(mDNS *const m, const domainname *const name, const mDNSu32 namehash, mDNSBool *purge)
+mDNSlocal mDNSs32 CheckForSoonToExpireRecords(mDNS *const m, const domainname *const name, const mDNSu32 namehash)
{
- const mDNSs32 threshhold = m->timenow + mDNSPlatformOneSecond; // See if there are any records expiring within one second
+ const mDNSs32 threshold = 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, namehash, name);
const CacheRecord *rr;
- if (purge)
- *purge = mDNSfalse;
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
{
- // If there are records that will expire soon, there are cases that need delayed
- // delivery of events:
- //
- // 1) A new cache entry is about to be added as a replacement. The caller needs to
- // deliver a RMV (for the current old entry) followed by ADD (for the new entry).
- // It needs to schedule the timer for the next cache expiry (ScheduleNextCacheCheckTime),
- // so that the cache entry can be purged (purging causes the RMV followed by ADD)
- //
- // 2) A new question is about to be answered and the caller needs to know whether it's
- // scheduling should be delayed so that the question is not answered with this record.
- // Instead of delivering an ADD (old entry) followed by RMV (old entry) and another ADD
- // (new entry), a single ADD can be delivered by delaying the scheduling of the question
- // immediately.
- //
- // When the unicast cache record is created, it's TTL has been extended beyond its value
- // given in the resource record (See RRAdjustTTL). If it is in the "extended" time, the
- // cache is already expired and we set "purge" to indicate that. When "purge" is set, the
- // return value of the function should be ignored by the callers.
- //
- // Note: For case (1), "purge" argument is NULL and hence the following checks are skipped.
- // It is okay to skip in that case because the cache records have been set to expire almost
- // immediately and the extended time does not apply.
- //
- // Also, if there is already an active question we don't try to optimize as purging the cache
- // would end up delivering RMV for the active question and hence we avoid that.
-
- if (purge && !rr->resrec.InterfaceID && !rr->CRActiveQuestion && rr->resrec.rroriginalttl)
- {
- mDNSu32 uTTL = RRUnadjustedTTL(rr->resrec.rroriginalttl);
- if (m->timenow - (rr->TimeRcvd + ((mDNSs32)uTTL * mDNSPlatformOneSecond)) >= 0)
- {
- LogInfo("CheckForSoonToExpireRecords: %s: rroriginalttl %u, unadjustedTTL %u, currentTTL %u",
- CRDisplayString(m, rr), rr->resrec.rroriginalttl, uTTL, (m->timenow - rr->TimeRcvd)/mDNSPlatformOneSecond);
- *purge = mDNStrue;
- continue;
- }
- }
- if (threshhold - RRExpireTime(rr) >= 0) // If we have records about to expire within a second
+ if (threshold - RRExpireTime(rr) >= 0) // If we have records about to expire within a second
{
if (delay - RRExpireTime(rr) < 0) // then delay until after they've been deleted
delay = RRExpireTime(rr);
@@ -4400,6 +4391,7 @@ mDNSlocal void CacheRecordAdd(mDNS *const m, CacheRecord *rr)
{
if (ResourceRecordAnswersQuestion(&rr->resrec, q))
{
+ mDNSIPPort zp = zeroIPPort;
// If this question is one that's actively sending queries, and it's received ten answers within one
// second of sending the last query packet, then that indicates some radical network topology change,
// so reset its exponential backoff back to the start. We must be at least at the eight-second interval
@@ -4422,7 +4414,7 @@ mDNSlocal void CacheRecordAdd(mDNS *const m, CacheRecord *rr)
verbosedebugf("CacheRecordAdd %p %##s (%s) %lu %#a:%d question %p", rr, rr->resrec.name->c,
DNSTypeName(rr->resrec.rrtype), rr->resrec.rroriginalttl, rr->resrec.rDNSServer ?
&rr->resrec.rDNSServer->addr : mDNSNULL, mDNSVal16(rr->resrec.rDNSServer ?
- rr->resrec.rDNSServer->port : zeroIPPort), q);
+ rr->resrec.rDNSServer->port : zp), q);
q->CurrentAnswers++;
q->unansweredQueries = 0;
@@ -4513,16 +4505,19 @@ mDNSlocal void CacheRecordRmv(mDNS *const m, CacheRecord *rr)
// response. A cache may be present that answers this question e.g., cache entry generated
// before the question became suppressed. We need to skip the suppressed questions here as
// the RMV event has already been generated.
- if (!QuerySuppressed(q) && ResourceRecordAnswersQuestion(&rr->resrec, q))
+ if (!QuerySuppressed(q) && ResourceRecordAnswersQuestion(&rr->resrec, q) &&
+ (q->allowExpired == AllowExpired_None || rr->resrec.mortality == Mortality_Mortal))
{
verbosedebugf("CacheRecordRmv %p %s", rr, CRDisplayString(m, rr));
q->FlappingInterface1 = mDNSNULL;
q->FlappingInterface2 = mDNSNULL;
- if (q->CurrentAnswers == 0)
+ if (q->CurrentAnswers == 0) {
+ mDNSIPPort zp = zeroIPPort;
LogMsg("CacheRecordRmv ERROR!!: How can CurrentAnswers already be zero for %p %##s (%s) DNSServer %#a:%d",
q, q->qname.c, DNSTypeName(q->qtype), q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL,
- mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zeroIPPort));
+ mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zp));
+ }
else
{
q->CurrentAnswers--;
@@ -4542,11 +4537,11 @@ mDNSlocal void CacheRecordRmv(mDNS *const m, CacheRecord *rr)
}
if (rr->resrec.rdata->MaxRDLength) // Never generate "remove" events for negative results
{
- if (q->CurrentAnswers == 0)
+ if ((q->CurrentAnswers == 0) && mDNSOpaque16IsZero(q->TargetQID))
{
LogInfo("CacheRecordRmv: Last answer for %##s (%s) expired from cache; will reconfirm antecedents",
q->qname.c, DNSTypeName(q->qtype));
- ReconfirmAntecedents(m, &q->qname, q->qnamehash, 0);
+ ReconfirmAntecedents(m, &q->qname, q->qnamehash, rr->resrec.InterfaceID, 0);
}
AnswerCurrentQuestionWithResourceRecord(m, rr, QC_rmv);
}
@@ -4670,16 +4665,15 @@ mDNSlocal void CheckCacheExpiration(mDNS *const m, const mDNSu32 slot, CacheGrou
while (*rp)
{
CacheRecord *const rr = *rp;
+ mDNSBool recordReleased = mDNSfalse;
mDNSs32 event = RRExpireTime(rr);
if (m->timenow - event >= 0) // If expired, delete it
{
- *rp = rr->next; // Cut it from the list
-
- verbosedebugf("CheckCacheExpiration: Deleting%7d %7d %p %s",
- m->timenow - rr->TimeRcvd, rr->resrec.rroriginalttl, rr->CRActiveQuestion, CRDisplayString(m, rr));
if (rr->CRActiveQuestion) // If this record has one or more active questions, tell them it's going away
{
DNSQuestion *q = rr->CRActiveQuestion;
+ verbosedebugf("CheckCacheExpiration: Removing%7d %7d %p %s",
+ m->timenow - rr->TimeRcvd, rr->resrec.rroriginalttl, rr->CRActiveQuestion, CRDisplayString(m, rr));
// When a cache record is about to expire, we expect to do four queries at 80-82%, 85-87%, 90-92% and
// then 95-97% of the TTL. If the DNS server does not respond, then we will remove the cache entry
// before we pick a new DNS server. As the question interval is set to MaxQuestionInterval, we may
@@ -4696,9 +4690,30 @@ mDNSlocal void CheckCacheExpiration(mDNS *const m, const mDNSu32 slot, CacheGrou
CacheRecordRmv(m, rr);
m->rrcache_active--;
}
- ReleaseCacheRecord(m, rr);
+
+ event += MAX_GHOST_TIME; // Adjust so we can check for a ghost expiration
+ if (rr->resrec.mortality == Mortality_Mortal || // Normal expired mortal record that needs released
+ (rr->resrec.mortality == Mortality_Ghost && m->timenow - event >= 0)) // A ghost record that expired more than MAX_GHOST_TIME ago
+ { // Release as normal
+ *rp = rr->next; // Cut it from the list before ReleaseCacheRecord
+ verbosedebugf("CheckCacheExpiration: Deleting (%s)%7d %7d %p %s",
+ MortalityDisplayString(rr->resrec.mortality),
+ m->timenow - rr->TimeRcvd, rr->resrec.rroriginalttl, rr->CRActiveQuestion, CRDisplayString(m, rr));
+ ReleaseCacheRecord(m, rr);
+ recordReleased = mDNStrue;
+ }
+ else // An immortal record needs to become a ghost when it expires
+ { // Don't release this entry
+ if (rr->resrec.mortality == Mortality_Immortal)
+ {
+ rr->resrec.mortality = Mortality_Ghost; // Expired immortal records become ghosts
+ verbosedebugf("CheckCacheExpiration: NOT Deleting (%s)%7d %7d %p %s",
+ MortalityDisplayString(rr->resrec.mortality),
+ m->timenow - rr->TimeRcvd, rr->resrec.rroriginalttl, rr->CRActiveQuestion, CRDisplayString(m, rr));
+ }
+ }
}
- else // else, not expired; see if we need to query
+ else // else, not expired; see if we need to query
{
// If waiting to delay delivery, do nothing until then
if (rr->DelayDelivery && rr->DelayDelivery - m->timenow > 0)
@@ -4721,6 +4736,10 @@ mDNSlocal void CheckCacheExpiration(mDNS *const m, const mDNSu32 slot, CacheGrou
}
}
}
+ }
+
+ if (!recordReleased) // Schedule if we did not release the record
+ {
verbosedebugf("CheckCacheExpiration:%6d %5d %s",
(event - m->timenow) / mDNSPlatformOneSecond, CacheCheckGracePeriod(rr), CRDisplayString(m, rr));
if (m->rrcache_nextcheck[slot] - event > 0)
@@ -4774,7 +4793,7 @@ mDNSlocal mDNSBool AnswerQuestionWithLORecord(mDNS *const m, DNSQuestion *q, mDN
m->CurrentRecord = mDNSNULL;
return mDNStrue;
}
- AnswerLocalQuestionWithLocalAuthRecord(m, rr, mDNStrue);
+ AnswerLocalQuestionWithLocalAuthRecord(m, rr, QC_add);
if (m->CurrentQuestion != q)
break; // If callback deleted q, then we're finished here
}
@@ -4932,12 +4951,7 @@ mDNSlocal void AnswerNewQuestion(mDNS *const m)
{
// SecsSinceRcvd is whole number of elapsed seconds, rounded down
mDNSu32 SecsSinceRcvd = ((mDNSu32)(m->timenow - rr->TimeRcvd)) / mDNSPlatformOneSecond;
- if (rr->resrec.rroriginalttl <= SecsSinceRcvd)
- {
- LogMsg("AnswerNewQuestion: How is rr->resrec.rroriginalttl %lu <= SecsSinceRcvd %lu for %s %d %d",
- rr->resrec.rroriginalttl, SecsSinceRcvd, CRDisplayString(m, rr), m->timenow, rr->TimeRcvd);
- continue; // Go to next one in loop
- }
+ if (rr->resrec.rroriginalttl <= SecsSinceRcvd && q->allowExpired != AllowExpired_AllowExpiredAnswers) continue; // Go to next one in loop
// If this record set is marked unique, then that means we can reasonably assume we have the whole set
// -- we don't need to rush out on the network and query immediately to see if there are more answers out there
@@ -4947,6 +4961,9 @@ mDNSlocal void AnswerNewQuestion(mDNS *const m)
if (rr->resrec.rdlength > SmallRecordLimit) q->LargeAnswers++;
if (rr->resrec.RecordType & kDNSRecordTypePacketUniqueMask) q->UniqueAnswers++;
AnsweredFromCache = mDNStrue;
+#if AWD_METRICS
+ if (q->metrics.expiredAnswerState == ExpiredAnswer_Allowed) q->metrics.expiredAnswerState = ExpiredAnswer_AnsweredWithExpired;
+#endif
AnswerCurrentQuestionWithResourceRecord(m, rr, QC_add);
if (m->CurrentQuestion != q) break; // If callback deleted q, then we're finished here
}
@@ -4969,6 +4986,21 @@ mDNSlocal void AnswerNewQuestion(mDNS *const m)
if (m->CurrentQuestion != q) { debugf("AnswerNewQuestion: Question deleted while giving negative answer"); goto exit; }
+ if (q->allowExpired == AllowExpired_AllowExpiredAnswers)
+ {
+ q->allowExpired = AllowExpired_MakeAnswersImmortal; // After looking through the cache for an answer, demote to make immortal
+ if (q->firstExpiredQname.c[0]) // If an original query name was saved on an expired answer, start it over in case it is updated
+ {
+ LogMsg("AnswerNewQuestion: Restarting original question %p firstExpiredQname %##s for allowExpiredAnswers question", q, &q->firstExpiredQname.c);
+ mDNS_StopQuery_internal(m, q); // Stop old query
+ AssignDomainName(&q->qname, &q->firstExpiredQname); // Update qname
+ q->qnamehash = DomainNameHashValue(&q->qname); // and namehash
+ mDNS_StartQuery_internal(m, q); // start new query
+ q->CNAMEReferrals = 0; // Reset referral count
+ q->firstExpiredQname.c[0] = 0; // Erase the domain name
+ }
+ }
+
// Note: When a query gets suppressed or retried with search domains, we de-activate the question.
// Hence we don't execute the following block of code for those cases.
if (ShouldQueryImmediately && ActiveQuestion(q))
@@ -5270,7 +5302,7 @@ mDNSlocal void CheckRmvEventsForLocalRecords(mDNS *const m)
{
debugf("CheckRmvEventsForLocalRecords: Generating local RMV events for %s", ARDisplayString(m, rr));
rr->resrec.RecordType = kDNSRecordTypeShared;
- AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse);
+ AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, QC_rmv);
if (m->CurrentRecord == rr) // If rr still exists in list, restore its state now
{
rr->resrec.RecordType = kDNSRecordTypeDeregistering;
@@ -5481,7 +5513,7 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
if (LocalRecordReady(rr))
{
debugf("mDNS_Execute: Delivering Add event with LocalAuthRecord %s", ARDisplayString(m, rr));
- AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNStrue);
+ AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, QC_add);
}
else if (!rr->next)
{
@@ -5538,7 +5570,7 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
if (LocalRecordReady(rr))
{
debugf("mDNS_Execute: Delivering Add event with LocalAuthRecord %s", ARDisplayString(m, rr));
- AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNStrue);
+ AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, QC_add);
}
else LogMsg("mDNS_Execute: LocalOnlyRecord %s not ready", ARDisplayString(m, rr));
}
@@ -6075,7 +6107,7 @@ mDNSexport mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkIn
}
if ((intf != mDNSNULL) && (mti.IntfId != intf->InterfaceID))
{
- LogInfo("mDNSPlatformRetrieveTCPInfo: InterfaceID mismatch mti.IntfId = %p InterfaceID = %p", mti.IntfId, intf->InterfaceID);
+ LogInfo("mDNSPlatformRetrieveTCPInfo: InterfaceID mismatch mti.IntfId = %p InterfaceID = %p", mti.IntfId, intf->InterfaceID);
return mStatus_BadParamErr;
}
@@ -6644,6 +6676,7 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
NetworkInterfaceInfo *intf;
for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
{
+ mDNSBool skipFullSleepProxyRegistration = mDNSfalse;
// Intialize it to false. These values make sense only when SleepState is set to Sleeping.
intf->SendGoodbyes = 0;
@@ -6670,18 +6703,21 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
continue;
}
- // Check if we have already registered with a sleep proxy for this subnet
+ // Check if we have already registered with a sleep proxy for this subnet.
+ // If so, then the subsequent in-NIC sleep proxy registration is limited to any keepalive records that belong
+ // to the interface.
if (skipSameSubnetRegistration(m, registeredIntfIDS, registeredCount, intf->InterfaceID))
{
- LogSPS("%s : Skipping sleep proxy registration on %s", __func__, intf->ifname);
- continue;
+ LogSPS("%s : Skipping full sleep proxy registration on %s", __func__, intf->ifname);
+ skipFullSleepProxyRegistration = mDNStrue;
}
#if APPLE_OSX_mDNSResponder
- else if (SupportsInNICProxy(intf))
+ if (SupportsInNICProxy(intf))
{
mDNSBool keepaliveOnly = mDNSfalse;
- if (ActivateLocalProxy(intf, &keepaliveOnly) == mStatus_NoError)
+ const mStatus err = ActivateLocalProxy(intf, skipFullSleepProxyRegistration, &keepaliveOnly);
+ if (!skipFullSleepProxyRegistration && !err)
{
SendGoodbyesForWakeOnlyService(m, &WakeOnlyService);
@@ -6699,9 +6735,10 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
registeredIntfIDS[registeredCount] = intf->InterfaceID;
registeredCount++;
}
+ continue;
}
#endif // APPLE_OSX_mDNSResponder
- else
+ if (!skipFullSleepProxyRegistration)
{
#if APPLE_OSX_mDNSResponder
// If on battery, do not attempt to offload to external sleep proxies
@@ -6827,7 +6864,13 @@ mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleep)
#endif
mDNS_ReclaimLockAfterCallback();
}
-
+#ifdef _LEGACY_NAT_TRAVERSAL_
+ if (m->SSDPSocket)
+ {
+ mDNSPlatformUDPClose(m->SSDPSocket);
+ m->SSDPSocket = mDNSNULL;
+ }
+#endif
m->SleepState = SleepState_Transferring;
if (m->SystemWakeOnLANEnabled && m->DelaySleep)
{
@@ -7148,7 +7191,7 @@ mDNSlocal mDNSu8 *GenerateUnicastResponse(const DNSMessage *const query, const m
const mDNSu8 *const limit = response->data + sizeof(response->data);
const mDNSu8 *ptr = query->data;
AuthRecord *rr;
- mDNSu32 maxttl = 0x70000000;
+ mDNSu32 maxttl = mDNSMaximumTTLSeconds;
int i;
// Initialize the response fields so we can answer the questions
@@ -7500,6 +7543,7 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
AuthRecord **nrp = &ResponseRecords;
#if POOF_ENABLED
+ mDNSBool notD2D = !mDNSPlatformInterfaceIsD2D(InterfaceID); // We don't run the POOF algorithm on D2D interfaces.
CacheRecord *ExpectedAnswers = mDNSNULL; // Records in our cache we expect to see updated
CacheRecord **eap = &ExpectedAnswers;
#endif // POOF_ENABLED
@@ -7659,18 +7703,21 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
if (QuestionNeedsMulticastResponse && !(query->h.flags.b[0] & kDNSFlag0_TC))
{
#if POOF_ENABLED
- 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
- 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 (notD2D)
+ {
+ 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
+ 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;
+ }
+ }
#endif // POOF_ENABLED
// Check if this question is the same as any of mine.
@@ -7761,15 +7808,18 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
ourcacherr = FindIdenticalRecordInCache(m, &m->rec.r.resrec);
#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.
- eap = &ExpectedAnswers;
- while (*eap)
+ if (notD2D)
{
- CacheRecord *cr = *eap;
- if (cr->resrec.InterfaceID == InterfaceID && IdenticalResourceRecord(&m->rec.r.resrec, &cr->resrec))
- { *eap = cr->NextInKAList; cr->NextInKAList = mDNSNULL; }
- else eap = &cr->NextInKAList;
+ // 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.
+ eap = &ExpectedAnswers;
+ while (*eap)
+ {
+ CacheRecord *cr = *eap;
+ if (cr->resrec.InterfaceID == InterfaceID && IdenticalResourceRecord(&m->rec.r.resrec, &cr->resrec))
+ { *eap = cr->NextInKAList; cr->NextInKAList = mDNSNULL; }
+ else eap = &cr->NextInKAList;
+ }
}
#endif // POOF_ENABLED
@@ -7933,7 +7983,7 @@ exit:
}
#if POOF_ENABLED
- while (ExpectedAnswers)
+ while (ExpectedAnswers && notD2D)
{
CacheRecord *cr = ExpectedAnswers;
ExpectedAnswers = cr->NextInKAList;
@@ -8045,19 +8095,25 @@ struct UDPSocket_struct
mDNSIPPort port; // MUST BE FIRST FIELD -- mDNSCoreReceive expects every UDPSocket_struct to begin with mDNSIPPort port
};
-mDNSlocal DNSQuestion *ExpectingUnicastResponseForQuestion(const mDNS *const m, const mDNSIPPort port, const mDNSOpaque16 id, const DNSQuestion *const question, mDNSBool tcp)
+mDNSlocal DNSQuestion *ExpectingUnicastResponseForQuestion(const mDNS *const m, const mDNSIPPort port, const mDNSOpaque16 id, const DNSQuestion *const question, mDNSBool tcp, DNSQuestion ** suspiciousQ)
{
DNSQuestion *q;
for (q = m->Questions; q; q=q->next)
{
if (!tcp && !q->LocalSocket) continue;
- if (mDNSSameIPPort(tcp ? q->tcpSrcPort : q->LocalSocket->port, port) &&
- mDNSSameOpaque16(q->TargetQID, id) &&
+ if (mDNSSameIPPort(tcp ? q->tcpSrcPort : q->LocalSocket->port, port) &&
q->qtype == question->qtype &&
q->qclass == question->qclass &&
q->qnamehash == question->qnamehash &&
SameDomainName(&q->qname, &question->qname))
- return(q);
+ {
+ if (mDNSSameOpaque16(q->TargetQID, id)) return(q);
+ else
+ {
+ if (!tcp && suspiciousQ) *suspiciousQ = q;
+ return(mDNSNULL);
+ }
+ }
}
return(mDNSNULL);
}
@@ -8084,7 +8140,10 @@ mDNSlocal DNSQuestion *ExpectingUnicastResponseForRecord(mDNS *const m,
mDNSIPPort srcp;
if (!tcp)
{
- srcp = q->LocalSocket ? q->LocalSocket->port : zeroIPPort;
+ if (q->LocalSocket)
+ srcp = q->LocalSocket->port;
+ else
+ srcp = zeroIPPort;
}
else
{
@@ -8139,10 +8198,11 @@ mDNSexport CacheRecord *CreateNewCacheEntry(mDNS *const m, const mDNSu32 slot, C
if (!rr) NoCacheAnswer(m, &m->rec.r);
else
{
- RData *saveptr = rr->resrec.rdata; // Save the rr->resrec.rdata pointer
- *rr = m->rec.r; // Block copy the CacheRecord object
- rr->resrec.rdata = saveptr; // Restore rr->resrec.rdata after the structure assignment
- rr->resrec.name = cg->name; // And set rr->resrec.name to point into our CacheGroup header
+ RData *saveptr = rr->resrec.rdata; // Save the rr->resrec.rdata pointer
+ *rr = m->rec.r; // Block copy the CacheRecord object
+ rr->resrec.rdata = saveptr; // Restore rr->resrec.rdata after the structure assignment
+ rr->resrec.name = cg->name; // And set rr->resrec.name to point into our CacheGroup header
+ rr->resrec.mortality = Mortality_Mortal;
// We need to add the anonymous info before we call CacheRecordAdd so that
// if it finds a matching question with this record, it bumps up the counters like
@@ -8209,6 +8269,7 @@ mDNSlocal void RefreshCacheRecord(mDNS *const m, CacheRecord *rr, mDNSu32 ttl)
rr->TimeRcvd = m->timenow;
rr->resrec.rroriginalttl = ttl;
rr->UnansweredQueries = 0;
+ if (rr->resrec.mortality != Mortality_Mortal) rr->resrec.mortality = Mortality_Immortal;
SetNextCacheCheckTimeForRecord(m, rr);
}
@@ -8279,7 +8340,7 @@ mDNSlocal mDNSBool IsResponseAcceptable(mDNS *const m, const CacheRecord *crlist
if (target && cr->resrec.rdatahash == rr->namehash && SameDomainName(target, rr->name))
{
- LogInfo("IsResponseAcceptable: Found a matching entry for %##s in the CacheFlushRecords %s", rr->name->c, CRDisplayString(m, cr));
+ LogDebug("IsResponseAcceptable: Found a matching entry for %##s in the CacheFlushRecords %s", rr->name->c, CRDisplayString(m, cr));
return (mDNStrue);
}
}
@@ -8381,7 +8442,7 @@ mDNSlocal void mDNSCoreReceiveNoDNSSECAnswers(mDNS *const m, const DNSMessage *c
DNSQuestion pktq;
DNSQuestion *qptr = mDNSNULL;
ptr = getQuestion(response, ptr, end, InterfaceID, &pktq);
- if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &pktq, !dstaddr)) &&
+ if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &pktq, !dstaddr, mDNSNULL)) &&
qptr->ValidatingResponse)
{
DNSQuestion *next, *q;
@@ -8425,7 +8486,7 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
DNSQuestion q;
DNSQuestion *qptr = mDNSNULL;
ptr = getQuestion(response, ptr, end, InterfaceID, &q);
- if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q, !dstaddr)))
+ if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q, !dstaddr, mDNSNULL)))
{
CacheRecord *rr, *neg = mDNSNULL;
CacheGroup *cg = CacheGroupForName(m, q.qnamehash, &q.qname);
@@ -8777,6 +8838,12 @@ mDNSlocal CacheRecord* mDNSCoreReceiveCacheCheck(mDNS *const m, const DNSMessage
DNSQuestion *q;
m->mDNSStats.CacheRefreshed++;
+
+ if (rr->resrec.mortality == Mortality_Ghost && unicastQuestion && (unicastQuestion->allowExpired != AllowExpired_AllowExpiredAnswers) && !rr->DelayDelivery)
+ {
+ rr->DelayDelivery = NonZeroTime(m->timenow);
+ debugf("mDNSCoreReceiveCacheCheck: Reset DelayDelivery for mortalityExpired EXP:%d RR %s", m->timenow - RRExpireTime(rr), CRDisplayString(m, rr));
+ }
if (rr->resrec.rroriginalttl == 0) debugf("uDNS rescuing %s", CRDisplayString(m, rr));
RefreshCacheRecord(m, rr, m->rec.r.resrec.rroriginalttl);
@@ -8944,6 +9011,13 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
response->h.numAuthorities, response->h.numAuthorities == 1 ? "y, " : "ies,",
response->h.numAdditionals, response->h.numAdditionals == 1 ? " " : "s", end - response->data, LLQType);
+#if AWD_METRICS
+ if (mDNSSameIPPort(srcport, UnicastDNSPort))
+ {
+ MetricsUpdateDNSResponseSize((mDNSu32)(end - (mDNSu8 *)response));
+ }
+#endif
+
// According to RFC 2181 <http://www.ietf.org/rfc/rfc2181.txt>
// When a DNS client receives a reply with TC
// set, it should ignore that response, and query again, using a
@@ -8956,18 +9030,25 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
// abort our TCP connection, and not complete the operation, and end up with an incomplete RRSet in our cache.
// Next time there's a query for this RRSet we'll see answers in our cache, and assume we have the whole RRSet already,
// and not even do the TCP query.
- // Accordingly, if we get a uDNS reply with kDNSFlag0_TC set, we bail out and wait for the TCP response containing the entire RRSet.
- if (!InterfaceID && (response->h.flags.b[0] & kDNSFlag0_TC)) return;
+ // Accordingly, if we get a uDNS reply with kDNSFlag0_TC set, we bail out and wait for the TCP response containing the
+ // entire RRSet, with the following exception. If the response contains an answer section and one or more records in
+ // either the authority section or additional section, then that implies that truncation occurred beyond the answer
+ // section, and the answer section is therefore assumed to be complete.
+ //
+ // From section 6.2 of RFC 1035 <https://tools.ietf.org/html/rfc1035>:
+ // When a response is so long that truncation is required, the truncation
+ // should start at the end of the response and work forward in the
+ // datagram. Thus if there is any data for the authority section, the
+ // answer section is guaranteed to be unique.
+ if (!InterfaceID && (response->h.flags.b[0] & kDNSFlag0_TC) &&
+ ((response->h.numAnswers == 0) || ((response->h.numAuthorities == 0) && (response->h.numAdditionals == 0)))) return;
if (LLQType == uDNS_LLQ_Ignore) return;
// 1. We ignore questions (if any) in mDNS response packets
// 2. If this is an LLQ response, we handle it much the same
- // 3. If we get a uDNS UDP response with the TC (truncated) bit set, then we can't treat this
- // answer as being the authoritative complete RRSet, and respond by deleting all other
- // matching cache records that don't appear in this packet.
// Otherwise, this is a authoritative uDNS answer, so arrange for any stale records to be purged
- if (ResponseMCast || LLQType == uDNS_LLQ_Events || (response->h.flags.b[0] & kDNSFlag0_TC))
+ if (ResponseMCast || LLQType == uDNS_LLQ_Events)
ptr = LocateAnswers(response, end);
// Otherwise, for one-shot queries, any answers in our cache that are not also contained
// in this response packet are immediately deemed to be invalid.
@@ -8985,9 +9066,9 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
// packet number, then we deduce they are old and delete them
for (i = 0; i < response->h.numQuestions && ptr && ptr < end; i++)
{
- DNSQuestion q, *qptr = mDNSNULL;
+ DNSQuestion q, *qptr = mDNSNULL, *suspiciousForQ = mDNSNULL;
ptr = getQuestion(response, ptr, end, InterfaceID, &q);
- if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q, !dstaddr)))
+ if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q, !dstaddr, &suspiciousForQ)))
{
if (!failure)
{
@@ -9050,6 +9131,15 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
returnEarly = mDNStrue;
}
}
+ else if (!InterfaceID && suspiciousForQ)
+ {
+ // If a response is suspicious for a question, then reissue the question via TCP
+ LogInfo("mDNSCoreReceiveResponse: Server %p responded suspiciously to query %##s (%s) qID %d != rID: %d",
+ suspiciousForQ->qDNSServer, q.qname.c, DNSTypeName(q.qtype),
+ mDNSVal16(suspiciousForQ->TargetQID), mDNSVal16(response->h.id));
+ uDNS_RestartQuestionAsTCP(m, suspiciousForQ, srcaddr, srcport);
+ return;
+ }
}
if (returnEarly)
{
@@ -9184,6 +9274,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
{
debugf("mDNSCoreReceiveResponse: InterfaceID %p %##s (%s)", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
m->rec.r.resrec.rDNSServer = uDNSServer = q->qDNSServer;
+ if (!unicastQuestion) unicastQuestion = q; // Acceptable responses to unicast questions need to have (unicastQuestion != nil)
}
else
{
@@ -9413,7 +9504,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, mDNSNULL);
+ delay = CheckForSoonToExpireRecords(m, m->rec.r.resrec.name, m->rec.r.resrec.namehash);
// If unique, assume we may have to delay delivery of this 'add' event.
// Below, where we walk the CacheFlushRecords list, we either call CacheRecordDeferredAdd()
@@ -9481,6 +9572,7 @@ exit:
CacheRecord *r1 = CacheFlushRecords, *r2;
const mDNSu32 slot = HashSlotFromNameHash(r1->resrec.namehash);
const CacheGroup *cg = CacheGroupForRecord(m, &r1->resrec);
+ mDNSBool purgedRecords = mDNSfalse;
CacheFlushRecords = CacheFlushRecords->NextInCFList;
r1->NextInCFList = mDNSNULL;
@@ -9531,6 +9623,12 @@ exit:
r1->resrec.rrtype == r2->resrec.rrtype &&
r1->resrec.rrclass == r2->resrec.rrclass)
{
+ if (r1->resrec.mortality == Mortality_Mortal && r2->resrec.mortality != Mortality_Mortal)
+ {
+ verbosedebugf("mDNSCoreReceiveResponse: R1(%p) is being immortalized by R2(%p)", r1, r2);
+ r1->resrec.mortality = Mortality_Immortal; // Immortalize the replacement record
+ }
+
// If record is recent, just ensure the whole RRSet has the same TTL (as required by DNS semantics)
// else, if record is old, mark it to be flushed
if (m->timenow - r2->TimeRcvd < mDNSPlatformOneSecond && RRExpireTime(r2) - m->timenow > mDNSPlatformOneSecond)
@@ -9562,8 +9660,9 @@ exit:
r2->resrec.rroriginalttl = r1->resrec.rroriginalttl;
}
r2->TimeRcvd = m->timenow;
+ SetNextCacheCheckTimeForRecord(m, r2);
}
- else // else, if record is old, mark it to be flushed
+ else if (r2->resrec.InterfaceID) // else, if record is old, mark it to be flushed
{
verbosedebugf("Cache flush new %p age %d expire in %d %s", r1, m->timenow - r1->TimeRcvd, RRExpireTime(r1) - m->timenow, CRDisplayString(m, r1));
verbosedebugf("Cache flush old %p age %d expire in %d %s", r2, m->timenow - r2->TimeRcvd, RRExpireTime(r2) - m->timenow, CRDisplayString(m, r2));
@@ -9601,8 +9700,30 @@ exit:
// We use (m->timenow - 1) instead of m->timenow, because we use that to identify records
// that we marked for deletion via an explicit DE record
}
+ SetNextCacheCheckTimeForRecord(m, r2);
+ }
+ else
+ {
+#if AWD_METRICS
+ if (r2->resrec.mortality == Mortality_Ghost)
+ {
+ DNSQuestion * q;
+ for (q = m->Questions; q; q=q->next)
+ {
+ if (!q->LongLived && ActiveQuestion(q) &&
+ ResourceRecordAnswersQuestion(&r2->resrec, q) &&
+ q->metrics.expiredAnswerState == ExpiredAnswer_AnsweredWithExpired)
+ {
+ q->metrics.expiredAnswerState = ExpiredAnswer_ExpiredAnswerChanged;
+ }
+ }
+ }
+#endif
+ // Old uDNS records are scheduled to be purged instead of given at most one second to live.
+ r2->resrec.mortality = Mortality_Mortal; // We want it purged, so remove any immortality
+ mDNS_PurgeCacheResourceRecord(m, r2);
+ purgedRecords = mDNStrue;
}
- SetNextCacheCheckTimeForRecord(m, r2);
}
}
@@ -9630,7 +9751,16 @@ exit:
NSECRecords = mDNSNULL;
NSECCachePtr = mDNSNULL;
}
- r1->DelayDelivery = CheckForSoonToExpireRecords(m, r1->resrec.name, r1->resrec.namehash, mDNSNULL);
+ if (r1->resrec.InterfaceID)
+ {
+ r1->DelayDelivery = CheckForSoonToExpireRecords(m, r1->resrec.name, r1->resrec.namehash);
+ }
+ else
+ {
+ // If uDNS records from an older RRset were scheduled to be purged, then delay delivery slightly to allow
+ // them to be deleted before any ADD events for this record.
+ r1->DelayDelivery = purgedRecords ? NonZeroTime(m->timenow) : 0;
+ }
// 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);
@@ -9742,7 +9872,7 @@ mDNSlocal mDNSu8 *GetValueForMACAddr(mDNSu8 *ptr, mDNSu8 *limit, mDNSEthAddr *et
int i;
mDNSs8 hval = 0;
int colons = 0;
- mDNSu8 val = 0;
+ mDNSu16 val = 0; /* need to use 16 bit int to detect overflow */
for (i = 0; ptr < limit && *ptr != ' ' && i < 17; i++, ptr++)
{
@@ -9759,7 +9889,7 @@ mDNSlocal mDNSu8 *GetValueForMACAddr(mDNSu8 *ptr, mDNSu8 *limit, mDNSEthAddr *et
LogMsg("GetValueForMACAddr: Address malformed colons %d val %d", colons, val);
return mDNSNULL;
}
- eth->b[colons] = val;
+ eth->b[colons] = (mDNSs8)val;
colons++;
val = 0;
}
@@ -9769,7 +9899,7 @@ mDNSlocal mDNSu8 *GetValueForMACAddr(mDNSu8 *ptr, mDNSu8 *limit, mDNSEthAddr *et
LogMsg("GetValueForMACAddr: Address malformed colons %d", colons);
return mDNSNULL;
}
- eth->b[colons] = val;
+ eth->b[colons] = (mDNSs8)val;
return ptr;
}
@@ -10209,7 +10339,7 @@ mDNSlocal void mDNSCoreReceiveUpdate(mDNS *const m,
if (!InterfaceID || !m->SPSSocket || !mDNSSameIPPort(dstport, m->SPSSocket->port)) return;
if (mDNS_PacketLoggingEnabled)
- DumpPacket(m, mStatus_NoError, mDNSfalse, "UDP", srcaddr, srcport, dstaddr, dstport, msg, end);
+ DumpPacket(mStatus_NoError, mDNSfalse, "UDP", srcaddr, srcport, dstaddr, dstport, msg, end);
ptr = LocateOptRR(msg, end, DNSOpt_LeaseData_Space + DNSOpt_OwnerData_ID_Space);
if (ptr)
@@ -10468,7 +10598,6 @@ mDNSexport void MakeNegativeCacheRecord(mDNS *const m, CacheRecord *const cr,
cr->TimeRcvd = m->timenow;
cr->DelayDelivery = 0;
cr->NextRequiredQuery = m->timenow;
- cr->LastUsed = m->timenow;
cr->CRActiveQuestion = mDNSNULL;
cr->UnansweredQueries = 0;
cr->LastUnansweredTime = 0;
@@ -10563,7 +10692,7 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNS
{
ifid = mDNSInterface_Any;
if (mDNS_PacketLoggingEnabled)
- DumpPacket(m, mStatus_NoError, mDNSfalse, TLS ? "TLS" : !dstaddr ? "TCP" : "UDP", srcaddr, srcport, dstaddr, dstport, msg, end);
+ DumpPacket(mStatus_NoError, mDNSfalse, TLS ? "TLS" : !dstaddr ? "TCP" : "UDP", srcaddr, srcport, dstaddr, dstport, msg, end);
uDNS_ReceiveMsg(m, msg, end, srcaddr, srcport);
// Note: mDNSCore also needs to get access to received unicast responses
}
@@ -11128,11 +11257,11 @@ mDNSlocal DNSServer *GetServerForName(mDNS *m, const domainname *name, mDNSInter
curmatch = GetBestServer(m, name, InterfaceID, ServiceID, allValid, mDNSNULL, mDNStrue);
if (curmatch != mDNSNULL)
- LogInfo("GetServerForName: DNS server %#a:%d (Penalty Time Left %d) (Scope %s:%p) found for name %##s", &curmatch->addr,
+ LogInfo("GetServerForName: DNS server %#a:%d (Penalty Time Left %d) (Scope %s:%p) for %##s", &curmatch->addr,
mDNSVal16(curmatch->port), (curmatch->penaltyTime ? (curmatch->penaltyTime - m->timenow) : 0), ifname ? ifname : "None",
InterfaceID, name);
else
- LogInfo("GetServerForName: no DNS server (Scope %s:%p) found for name %##s", ifname ? ifname : "None", InterfaceID, name);
+ LogInfo("GetServerForName: no DNS server (Scope %s:%p) for %##s", ifname ? ifname : "None", InterfaceID, name);
return(curmatch);
}
@@ -11161,14 +11290,14 @@ mDNSexport DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question)
if (curmatch != mDNSNULL)
{
- LogInfo("GetServerForQuestion: %p DNS server (%p) %#a:%d (Penalty Time Left %d) (Scope %s:%p:%d) found for name %##s (%s)",
+ LogInfo("GetServerForQuestion: %p DNS server (%p) %#a:%d (Penalty Time Left %d) (Scope %s:%p:%d) for %##s (%s)",
question, curmatch, &curmatch->addr, mDNSVal16(curmatch->port),
(curmatch->penaltyTime ? (curmatch->penaltyTime - m->timenow) : 0), ifname ? ifname : "None",
InterfaceID, question->ServiceID, name, DNSTypeName(question->qtype));
}
else
{
- LogInfo("GetServerForQuestion: %p no DNS server (Scope %s:%p:%d) found for name %##s (%s)",
+ LogInfo("GetServerForQuestion: %p no DNS server (Scope %s:%p:%d) for %##s (%s)",
question, ifname ? ifname : "None", InterfaceID, question->ServiceID, name, DNSTypeName(question->qtype));
}
@@ -11212,6 +11341,8 @@ mDNSlocal mDNSBool IsPrivateDomain(mDNS *const m, DNSQuestion *q)
}
}
+#define TrueFalseStr(X) ((X) ? "true" : "false")
+
// This function takes the DNSServer as a separate argument because sometimes the
// caller has not yet assigned the DNSServer, but wants to evaluate the SuppressQuery
// status before switching to it.
@@ -11220,14 +11351,14 @@ mDNSlocal mDNSBool ShouldSuppressUnicastQuery(mDNS *const m, DNSQuestion *q, DNS
// Some callers don't check for the qtype
if (q->qtype != kDNSType_A && q->qtype != kDNSType_AAAA)
{
- LogInfo("ShouldSuppressUnicastQuery: Query not suppressed for %##s, qtype %s, not A/AAAA type", q->qname.c, DNSTypeName(q->qtype));
+ LogDebug("ShouldSuppressUnicastQuery: Query not suppressed for %##s, qtype %s, not A/AAAA type", q->qname.c, DNSTypeName(q->qtype));
return mDNSfalse;
}
// Private domains are exempted irrespective of what the DNSServer says
if (IsPrivateDomain(m, q))
{
- LogInfo("ShouldSuppressUnicastQuery: Query not suppressed for %##s, qtype %s, Private Domain", q->qname.c, DNSTypeName(q->qtype));
+ LogDebug("ShouldSuppressUnicastQuery: Query not suppressed for %##s, qtype %s, Private Domain", q->qname.c, DNSTypeName(q->qtype));
return mDNSfalse;
}
@@ -11238,28 +11369,35 @@ mDNSlocal mDNSBool ShouldSuppressUnicastQuery(mDNS *const m, DNSQuestion *q, DNS
}
// Check if the DNS Configuration allows A/AAAA queries to be sent
- if ((q->qtype == kDNSType_A) && (d->req_A))
+ if ((q->qtype == kDNSType_A) && d->req_A)
{
- LogInfo("ShouldSuppressUnicastQuery: Query not suppressed for %##s, qtype %s, DNSServer %##s %#a:%d allows A queries", q->qname.c,
- DNSTypeName(q->qtype), d->domain.c, &d->addr, mDNSVal16(d->port));
- return mDNSfalse;
+ // The server's configuration allows A record queries, so don't suppress this query unless
+ // 1. the interface associated with the server is CLAT46; and
+ // 2. the query has the kDNSServiceFlagsPathEvaluationDone flag, which indicates that it came from libnetcore.
+ // See <rdar://problem/42672030> for more info.
+ if (!(d->isCLAT46 && (q->flags & kDNSServiceFlagsPathEvaluationDone)))
+ {
+ LogDebug("ShouldSuppressUnicastQuery: Query not suppressed for %##s, qtype %s, DNSServer %##s %#a:%d allows A queries", q->qname.c,
+ DNSTypeName(q->qtype), d->domain.c, &d->addr, mDNSVal16(d->port));
+ return mDNSfalse;
+ }
}
- if ((q->qtype == kDNSType_AAAA) && (d->req_AAAA))
+ if ((q->qtype == kDNSType_AAAA) && d->req_AAAA)
{
- LogInfo("ShouldSuppressUnicastQuery: Query not suppressed for %##s, qtype %s, DNSServer %##s %#a:%d allows AAAA queries", q->qname.c,
+ LogDebug("ShouldSuppressUnicastQuery: Query not suppressed for %##s, qtype %s, DNSServer %##s %#a:%d allows AAAA queries", q->qname.c,
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));
+ LogDebug("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");
+ LogInfo("ShouldSuppressUnicastQuery: Query suppressed for %##s, qtype %s, since DNS Configuration does not allow (req_A %s, req_AAAA %s, CLAT46 %s)",
+ q->qname.c, DNSTypeName(q->qtype), TrueFalseStr(d->req_A), TrueFalseStr(d->req_AAAA), TrueFalseStr(d->isCLAT46));
return mDNStrue;
}
@@ -11642,8 +11780,8 @@ mDNSlocal mStatus ValidateParameters(mDNS *const m, DNSQuestion *const question)
return(mStatus_NoError);
}
-// InitDNSConfig() is called by InitCommonState() to initialize the DNS configuration of the Question.
-// These are a subset of the internal uDNS fields. Must be done before ShouldSuppressQuery() & mDNS_PurgeForQuestion()
+// InitDNSConfig() is called by InitCommonState() to initialize the DNS configuration of the Question.
+// These are a subset of the internal uDNS fields. Must be done before ShouldSuppressQuery() & mDNS_PurgeBeforeResolve()
mDNSlocal void InitDNSConfig(mDNS *const m, DNSQuestion *const question)
{
// First reset all DNS Configuration
@@ -11654,6 +11792,7 @@ mDNSlocal void InitDNSConfig(mDNS *const m, DNSQuestion *const question)
question->StopTime = (question->TimeoutQuestion) ? question->StopTime : 0;
#if AWD_METRICS
mDNSPlatformMemZero(&question->metrics, sizeof(question->metrics));
+ question->metrics.expiredAnswerState = (question->allowExpired != AllowExpired_None) ? ExpiredAnswer_Allowed : ExpiredAnswer_None;
#endif
// Need not initialize the DNS Configuration for Local Only OR P2P Questions when timeout not specified
@@ -11674,7 +11813,7 @@ mDNSlocal void InitDNSConfig(mDNS *const m, DNSQuestion *const question)
}
question->qDNSServer = GetServerForQuestion(m, question);
- LogInfo("InitDNSConfig: question %p %##s (%s) Timeout %d, DNS Server %#a:%d",
+ LogDebug("InitDNSConfig: question %p %##s (%s) Timeout %d, DNS Server %#a:%d",
question, question->qname.c, DNSTypeName(question->qtype), timeout,
question->qDNSServer ? &question->qDNSServer->addr : mDNSNULL,
mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zeroIPPort));
@@ -11699,9 +11838,8 @@ mDNSlocal void InitDNSConfig(mDNS *const m, DNSQuestion *const question)
// InitCommonState() is called by mDNS_StartQuery_internal() to initialize the common(uDNS/mDNS) internal
// state fields of the DNS Question. These are independent of the Client layer.
-mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
+mDNSlocal void InitCommonState(mDNS *const m, DNSQuestion *const question)
{
- mDNSBool purge;
int i;
mDNSBool isBlocked = mDNSfalse;
@@ -11720,7 +11858,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, &purge);
+ question->DelayAnswering = mDNSOpaque16IsZero(question->TargetQID) ? CheckForSoonToExpireRecords(m, &question->qname, question->qnamehash) : 0;
question->LastQTime = m->timenow;
question->ExpectUnicastResp = 0;
question->LastAnswerPktNum = m->PktNum;
@@ -11802,7 +11940,6 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
if (question->WakeOnResolve)
{
question->WakeOnResolveCount = InitialWakeOnResolveCount;
- purge = mDNStrue;
}
for (i=0; i<DupSuppressInfoSize; i++)
@@ -11819,8 +11956,6 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
if (question->DelayAnswering)
LogInfo("InitCommonState: Delaying answering for %d ticks while cache stabilizes for %##s (%s)",
question->DelayAnswering - m->timenow, question->qname.c, DNSTypeName(question->qtype));
-
- return(purge);
}
// Excludes the DNS Config fields which are already handled by InitDNSConfig()
@@ -11902,7 +12037,7 @@ mDNSlocal void InitDNSSECProxyState(mDNS *const m, DNSQuestion *const question)
// Once the question is completely initialized including the duplicate logic, this function
// is called to finalize the unicast question which requires flushing the cache if needed,
// activating the query etc.
-mDNSlocal void FinalizeUnicastQuestion(mDNS *const m, DNSQuestion *question, mDNSBool purge)
+mDNSlocal void FinalizeUnicastQuestion(mDNS *const m, DNSQuestion *question)
{
// Ensure DNS related info of duplicate question is same as the orig question
if (question->DuplicateOf)
@@ -11927,14 +12062,7 @@ mDNSlocal void FinalizeUnicastQuestion(mDNS *const m, DNSQuestion *question, mDN
ActivateUnicastQuery(m, question, mDNSfalse);
- // If purge was set above, flush the cache. Need to do this after we set the
- // DNS server on the question
- if (purge)
- {
- question->DelayAnswering = 0;
- mDNS_PurgeForQuestion(m, question);
- }
- else if (!question->DuplicateOf && DNSSECQuestion(question))
+ if (!question->DuplicateOf && DNSSECQuestion(question))
{
// For DNSSEC questions, we need to have the RRSIGs also for verification.
CheckForDNSSECRecords(m, question);
@@ -11957,7 +12085,6 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
{
DNSQuestion **q;
mStatus vStatus;
- mDNSBool purge;
// First check for cache space (can't do queries if there is no cache space allocated)
if (m->rrcache_size == 0)
@@ -12005,7 +12132,7 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
// InitCommonState -> InitDNSConfig) as DNS server selection affects DNSSEC
// validation.
- purge = InitCommonState(m, question);
+ InitCommonState(m, question);
InitWABState(question);
InitLLQState(question);
#ifdef DNS_PUSH_ENABLED
@@ -12038,7 +12165,7 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
// this routine with the question list data structures in an inconsistent state.
if (!mDNSOpaque16IsZero(question->TargetQID))
{
- FinalizeUnicastQuestion(m, question, purge);
+ FinalizeUnicastQuestion(m, question);
}
else
{
@@ -12058,10 +12185,10 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
}
}
#endif // BONJOUR_ON_DEMAND
- if (purge)
+ if (question->WakeOnResolve)
{
LogInfo("mDNS_StartQuery_internal: Purging for %##s", question->qname.c);
- mDNS_PurgeForQuestion(m, question);
+ mDNS_PurgeBeforeResolve(m, question);
}
}
}
@@ -12127,7 +12254,7 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
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);
+ MetricsUpdateDNSQueryStats(queryName, question->qtype, mDNSNULL, question->metrics.querySendCount, question->metrics.expiredAnswerState, durationMs, isForCell);
}
#endif
// Take care to cut question from list *before* calling UpdateQuestionDuplicates
@@ -12335,7 +12462,7 @@ mDNSexport mStatus mDNS_StopQueryWithRemoves(mDNS *const m, DNSQuestion *const q
{
// Don't use mDNS_DropLockBeforeCallback() here, since we don't allow API calls
if (question->QuestionCallback)
- question->QuestionCallback(m, question, &rr->resrec, mDNSfalse);
+ question->QuestionCallback(m, question, &rr->resrec, QC_rmv);
}
}
mDNS_Unlock(m);
@@ -12347,7 +12474,7 @@ mDNSexport mStatus mDNS_Reconfirm(mDNS *const m, CacheRecord *const cr)
mStatus status;
mDNS_Lock(m);
status = mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForNoAnswer);
- if (status == mStatus_NoError) ReconfirmAntecedents(m, cr->resrec.name, cr->resrec.namehash, 0);
+ if (status == mStatus_NoError) ReconfirmAntecedents(m, cr->resrec.name, cr->resrec.namehash, cr->resrec.InterfaceID, 0);
mDNS_Unlock(m);
return(status);
}
@@ -12360,7 +12487,7 @@ mDNSexport mStatus mDNS_ReconfirmByValue(mDNS *const m, ResourceRecord *const rr
cr = FindIdenticalRecordInCache(m, rr);
debugf("mDNS_ReconfirmByValue: %p %s", cr, RRDisplayString(m, rr));
if (cr) status = mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForNoAnswer);
- if (status == mStatus_NoError) ReconfirmAntecedents(m, cr->resrec.name, cr->resrec.namehash, 0);
+ if (status == mStatus_NoError) ReconfirmAntecedents(m, cr->resrec.name, cr->resrec.namehash, cr->resrec.InterfaceID, 0);
mDNS_Unlock(m);
return(status);
}
@@ -12876,7 +13003,7 @@ mDNSexport void mDNS_DeactivateNetWake_internal(mDNS *const m, NetworkInterfaceI
if (m->SPSBrowseCallback)
{
mDNS_DropLockBeforeCallback(); // Allow client to legally make mDNS API calls from the callback
- m->SPSBrowseCallback(m, &set->NetWakeBrowse, mDNSNULL, mDNSfalse);
+ m->SPSBrowseCallback(m, &set->NetWakeBrowse, mDNSNULL, QC_rmv);
mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
}
@@ -13166,6 +13293,7 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
}
else
{
+ rr->resrec.mortality = Mortality_Mortal;
mDNS_PurgeCacheResourceRecord(m, rr);
}
}
@@ -13363,7 +13491,7 @@ mDNSexport mDNSu32 deriveD2DFlagsFromAuthRecType(AuthRecType authRecType)
// If the optional target host parameter is set, then the storage it points to must remain valid for the lifetime of the service registration
mDNSexport mStatus mDNS_RegisterService(mDNS *const m, ServiceRecordSet *sr,
const domainlabel *const name, const domainname *const type, const domainname *const domain,
- const domainname *const host, mDNSIPPort port, const mDNSu8 txtinfo[], mDNSu16 txtlen,
+ const domainname *const host, mDNSIPPort port, RData *const txtrdata, const mDNSu8 txtinfo[], mDNSu16 txtlen,
AuthRecord *SubTypes, mDNSu32 NumSubTypes,
mDNSInterfaceID InterfaceID, mDNSServiceCallback Callback, void *Context, mDNSu32 flags)
{
@@ -13400,7 +13528,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, recordType, artype, ServiceCallback, sr);
+ mDNS_SetupResourceRecord(&sr->RR_TXT, txtrdata, 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))
@@ -13610,7 +13738,9 @@ mDNSexport mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordS
else debugf("%##s service (domain %##s) renamed from \"%#s\" to \"%#s\"",type.c, domain.c, name1.c, newname->c);
err = mDNS_RegisterService(m, sr, newname, &type, &domain,
- host, sr->RR_SRV.resrec.rdata->u.srv.port, sr->RR_TXT.resrec.rdata->u.txt.c, sr->RR_TXT.resrec.rdlength,
+ host, sr->RR_SRV.resrec.rdata->u.srv.port,
+ (sr->RR_TXT.resrec.rdata != &sr->RR_TXT.rdatastorage) ? sr->RR_TXT.resrec.rdata : mDNSNULL,
+ sr->RR_TXT.resrec.rdata->u.txt.c, sr->RR_TXT.resrec.rdlength,
sr->SubTypes, sr->NumSubTypes,
sr->RR_PTR.resrec.InterfaceID, sr->ServiceCallback, sr->ServiceContext, sr->flags);
@@ -13846,7 +13976,9 @@ mDNSlocal void mDNSCoreReceiveRawARP(mDNS *const m, const ARP_EthIP *const arp,
}
else if (msg == msg4)
{
- SendARP(m, 2, rr, (mDNSv4Addr *)arp->tpa.b, &arp->sha, (mDNSv4Addr *)arp->spa.b, &arp->sha);
+ mDNSv4Addr tpa = arp->tpa;
+ mDNSv4Addr spa = arp->spa;
+ SendARP(m, 2, rr, &tpa, &arp->sha, &spa, &arp->sha);
}
}
}
@@ -14249,6 +14381,7 @@ mDNSlocal void SleepProxyServerCallback(mDNS *const m, ServiceRecordSet *const s
mDNS_RegisterService(m, srs,
&name, &SleepProxyServiceType, &localdomain,
mDNSNULL, m->SPSSocket->port, // Host, port
+ mDNSNULL,
(mDNSu8 *)"", 1, // TXT data, length
mDNSNULL, 0, // Subtypes (none)
mDNSInterface_Any, // Interface ID
@@ -14611,7 +14744,7 @@ mDNSlocal void PurgeOrReconfirmCacheRecord(mDNS *const m, CacheRecord *cr, const
}
}
-mDNSlocal void mDNS_PurgeForQuestion(mDNS *const m, DNSQuestion *q)
+mDNSlocal void mDNS_PurgeBeforeResolve(mDNS *const m, DNSQuestion *q)
{
CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
CacheRecord *rp;
@@ -14627,7 +14760,7 @@ mDNSlocal void mDNS_PurgeForQuestion(mDNS *const m, DNSQuestion *q)
{
if (SameNameRecordAnswersQuestion(&rp->resrec, q))
{
- LogInfo("mDNS_PurgeForQuestion: Flushing %s", CRDisplayString(m, rp));
+ LogInfo("mDNS_PurgeBeforeResolve: Flushing %s", CRDisplayString(m, rp));
mDNS_PurgeCacheResourceRecord(m, rp);
}
}
@@ -14867,10 +15000,21 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
if (t != s)
{
mDNSBool old, new;
+ mDNSIPPort tport, sport;
+
+ if (t)
+ tport = t->port;
+ else
+ tport = zeroIPPort;
+
+ if (s)
+ sport = s->port;
+ else
+ sport = zeroIPPort;
// If DNS Server for this question has changed, reactivate it
LogInfo("uDNS_SetupDNSConfig: Updating DNS Server from %#a:%d (%##s) to %#a:%d (%##s) for question %##s (%s) (scope:%p)",
- t ? &t->addr : mDNSNULL, mDNSVal16(t ? t->port : zeroIPPort), t ? t->domain.c : (mDNSu8*)"",
- s ? &s->addr : mDNSNULL, mDNSVal16(s ? s->port : zeroIPPort), s ? s->domain.c : (mDNSu8*)"",
+ t ? &t->addr : mDNSNULL, mDNSVal16(tport), t ? t->domain.c : (mDNSu8*)"",
+ s ? &s->addr : mDNSNULL, mDNSVal16(sport), s ? s->domain.c : (mDNSu8*)"",
q->qname.c, DNSTypeName(q->qtype), q->InterfaceID);
old = q->SuppressQuery;
@@ -14919,8 +15063,9 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
}
else
{
+ mDNSIPPort zp = zeroIPPort;
debugf("uDNS_SetupDNSConfig: Not Updating DNS server question %p %##s (%s) DNS server %#a:%d %p %d",
- q, q->qname.c, DNSTypeName(q->qtype), t ? &t->addr : mDNSNULL, mDNSVal16(t ? t->port : zeroIPPort), q->DuplicateOf, q->SuppressUnusable);
+ q, q->qname.c, DNSTypeName(q->qtype), t ? &t->addr : mDNSNULL, mDNSVal16(t ? t->port : zp), q->DuplicateOf, q->SuppressUnusable);
for (qptr = q->next ; qptr; qptr = qptr->next)
if (qptr->DuplicateOf == q) { qptr->validDNSServers = q->validDNSServers; qptr->qDNSServer = q->qDNSServer; }
}
@@ -14967,6 +15112,7 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
{
LogInfo("uDNS_SetupDNSConfig: Purging Resourcerecord %s, New DNS server %#a , Old DNS server %#a", CRDisplayString(m, cr),
&ptr->addr, (cr->resrec.rDNSServer != mDNSNULL ? &cr->resrec.rDNSServer->addr : mDNSNULL));
+ cr->resrec.mortality = Mortality_Mortal;
mDNS_PurgeCacheResourceRecord(m, cr);
}
else
@@ -15035,6 +15181,7 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
cr->resrec.rDNSServer = mDNSNULL;
}
+ cr->resrec.mortality = Mortality_Mortal;
PurgeOrReconfirmCacheRecord(m, cr, ptr, mDNStrue);
}
}
diff --git a/usr/src/contrib/mDNSResponder/mDNSCore/mDNSDebug.h b/usr/src/contrib/mDNSResponder/mDNSCore/mDNSDebug.h
index 68a696ef8a..03ed8107fb 100755
--- a/usr/src/contrib/mDNSResponder/mDNSCore/mDNSDebug.h
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/mDNSDebug.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2018 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -87,9 +87,9 @@ extern "C" {
#define MDNS_GNU_VA_ARGS 0
#define MDNS_HAS_VA_ARG_MACROS 1
#else
- #define MDNS_C99_VA_ARGS 0
+ #define MDNS_C99_VA_ARGS 1
#define MDNS_GNU_VA_ARGS 0
- #define MDNS_HAS_VA_ARG_MACROS 0
+ #define MDNS_HAS_VA_ARG_MACROS 1
#endif
#if (MDNS_HAS_VA_ARG_MACROS)
@@ -99,12 +99,14 @@ extern "C" {
#define LogOperation(... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_OPERATION, __VA_ARGS__);} while (0)
#define LogSPS(... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_SPS, __VA_ARGS__);} while (0)
#define LogInfo(... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_INFO, __VA_ARGS__);} while (0)
+ #define LogDebug(... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_DEBUG, __VA_ARGS__);} while (0)
#elif (MDNS_GNU_VA_ARGS)
#define debug_noop( ARGS... ) ((void)0)
#define LogMsg( ARGS... ) LogMsgWithLevel(MDNS_LOG_MSG, ARGS)
#define LogOperation( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_OPERATION, ARGS);} while (0)
#define LogSPS( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_SPS, ARGS);} while (0)
#define LogInfo( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_INFO, ARGS);} while (0)
+ #define LogDebug( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_DEBUG, ARGS);} while (0)
#else
#error Unknown variadic macros
#endif
@@ -116,10 +118,12 @@ extern "C" {
#define LogOperation (mDNS_LoggingEnabled == 0) ? ((void)0) : LogOperation_
#define LogSPS (mDNS_LoggingEnabled == 0) ? ((void)0) : LogSPS_
#define LogInfo (mDNS_LoggingEnabled == 0) ? ((void)0) : LogInfo_
+ #define LogDebug (mDNS_LoggingEnabled == 0) ? ((void)0) : LogDebug_
extern void LogMsg_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
extern void LogOperation_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
extern void LogSPS_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
extern void LogInfo_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
+extern void LogDebug_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
#endif
#if MDNS_DEBUGMSGS
diff --git a/usr/src/contrib/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h b/usr/src/contrib/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
index cd52c20e53..772664fe02 100755
--- a/usr/src/contrib/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2018 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -101,6 +101,10 @@ extern "C" {
#define MaximumRDSize 264
#endif
+#if !defined(MDNSRESPONDER_BTMM_SUPPORT)
+#define MDNSRESPONDER_BTMM_SUPPORT 0
+#endif
+
// ***************************************************************************
// Function scope indicators
@@ -276,6 +280,8 @@ typedef struct mDNSInterfaceID_dummystruct { void *dummy; } *mDNSInterfaceID;
// find you get code that doesn't work consistently on big-endian and little-endian machines.
#if defined(_WIN32)
#pragma pack(push,2)
+#elif !defined(__GNUC__)
+ #pragma pack(1)
#endif
typedef union { mDNSu8 b[ 2]; mDNSu16 NotAnInteger; } mDNSOpaque16;
typedef union { mDNSu8 b[ 4]; mDNSu32 NotAnInteger; } mDNSOpaque32;
@@ -284,6 +290,8 @@ typedef union { mDNSu8 b[ 8]; mDNSu16 w[4]; mDNSu32 l[2]; } mDNSOpaque64;
typedef union { mDNSu8 b[16]; mDNSu16 w[8]; mDNSu32 l[4]; } mDNSOpaque128;
#if defined(_WIN32)
#pragma pack(pop)
+#elif !defined(__GNUC__)
+ #pragma pack()
#endif
typedef mDNSOpaque16 mDNSIPPort; // An IP port is a two-byte opaque identifier (not an integer)
@@ -1335,6 +1343,13 @@ typedef struct McastResolver
mDNSu32 timeout; // timeout value for questions
} McastResolver;
+enum {
+ Mortality_Mortal = 0, // This cache record can expire and get purged
+ Mortality_Immortal = 1, // Allow this record to remain in the cache indefinitely
+ Mortality_Ghost = 2 // An immortal record that has expired and can linger in the cache
+};
+typedef mDNSu8 MortalityState;
+
// scoped values for DNSServer matching
enum
{
@@ -1372,6 +1387,7 @@ typedef struct DNSServer
mDNSBool req_DO; // If set, okay to send DNSSEC queries (EDNS DO bit is supported)
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.
+ mDNSBool isCLAT46; // True if the interface to this server is CLAT46.
} DNSServer;
typedef struct
@@ -1386,6 +1402,7 @@ typedef struct
struct ResourceRecord_struct
{
mDNSu8 RecordType; // See kDNSRecordTypes enum.
+ MortalityState mortality; // Mortality of this resource record (See MortalityState enum)
mDNSu16 rrtype; // See DNS_TypeValues enum.
mDNSu16 rrclass; // See DNS_ClassValues enum.
mDNSu32 rroriginalttl; // In seconds
@@ -1399,7 +1416,6 @@ struct ResourceRecord_struct
// ReconfirmAntecedents(), etc., use rdatahash as a pre-flight check to see
// whether it's worth doing a full SameDomainName() call. If the rdatahash
// is not a correct case-insensitive name hash, they'll get false negatives.
-
// Grouping pointers together at the end of the structure improves the memory layout efficiency
mDNSInterfaceID InterfaceID; // Set if this RR is specific to one interface
// For records received off the wire, InterfaceID is *always* set to the receiving interface
@@ -1638,7 +1654,7 @@ struct CacheRecord_struct
mDNSs32 TimeRcvd; // In platform time units
mDNSs32 DelayDelivery; // Set if we want to defer delivery of this answer to local clients
mDNSs32 NextRequiredQuery; // In platform time units
- mDNSs32 LastUsed; // In platform time units
+ // Extra four bytes here (on 64bit)
DNSQuestion *CRActiveQuestion; // Points to an active question referencing this answer. Can never point to a NewQuestion.
mDNSs32 LastUnansweredTime; // In platform time units; last time we incremented UnansweredQueries
mDNSu8 UnansweredQueries; // Number of times we've issued a query for this record without getting an answer
@@ -1811,8 +1827,13 @@ typedef enum {
DNSPUSH_SERVERFOUND = 3,
DNSPUSH_ESTABLISHED = 4
} DNSPush_State;
-
-
+
+enum {
+ AllowExpired_None = 0, // Don't allow expired answers or mark answers immortal (behave normally)
+ AllowExpired_MakeAnswersImmortal = 1, // Any answers to this question get marked as immortal
+ AllowExpired_AllowExpiredAnswers = 2 // Allow already expired answers from the cache
+};
+typedef mDNSu8 AllowExpiredState;
#define HMAC_LEN 64
#define HMAC_IPAD 0x36
@@ -1896,16 +1917,29 @@ typedef enum { DNSSECValNotRequired = 0, DNSSECValRequired, DNSSECValInProgress,
// RFC 4122 defines it to be 16 bytes
#define UUID_SIZE 16
-#define AWD_METRICS (USE_AWD && TARGET_OS_EMBEDDED)
+#define AWD_METRICS (USE_AWD && TARGET_OS_IOS)
#if AWD_METRICS
-typedef struct
+
+enum
{
- domainname * originalQName; // Name of original A/AAAA record if this question is for a CNAME record.
- mDNSu32 querySendCount; // Number of queries that have been sent to DNS servers so far.
- mDNSs32 firstQueryTime; // The time when the first query was sent to a DNS server.
- mDNSBool answered; // Has this question been answered?
+ ExpiredAnswer_None = 0, // No expired answers used
+ ExpiredAnswer_Allowed = 1, // An expired answer is allowed by this request
+ ExpiredAnswer_AnsweredWithExpired = 2, // Question was answered with an expired answer
+ ExpiredAnswer_ExpiredAnswerChanged = 3, // Expired answer changed on refresh
+
+ ExpiredAnswer_EnumCount
+};
+typedef mDNSu8 ExpiredAnswerMetric;
+typedef struct
+{
+ domainname * originalQName; // Name of original A/AAAA record if this question is for a CNAME record.
+ mDNSu32 querySendCount; // Number of queries that have been sent to DNS servers so far.
+ mDNSs32 firstQueryTime; // The time when the first query was sent to a DNS server.
+ mDNSBool answered; // Has this question been answered?
+ ExpiredAnswerMetric expiredAnswerState; // Expired answer state (see ExpiredAnswerMetric above)
+
} uDNSMetrics;
#endif
@@ -1977,6 +2011,7 @@ struct DNSQuestion_struct
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
+ AllowExpiredState allowExpired; // Allow expired answers state (see enum AllowExpired_None, etc. above)
ZoneData *nta; // Used for getting zone data for private or LLQ query
mDNSAddr servAddr; // Address and port learned from _dns-llq, _dns-llq-tls or _dns-query-tls SRV query
@@ -2016,6 +2051,7 @@ struct DNSQuestion_struct
mDNSIPPort TargetPort; // Must be set if Target is set
mDNSOpaque16 TargetQID; // Must be set if Target is set
domainname qname;
+ domainname firstExpiredQname; // first expired qname in request chain
mDNSu16 qtype;
mDNSu16 qclass;
mDNSBool LongLived; // Set by client for calls to mDNS_StartQuery to indicate LLQs to unicast layer.
@@ -2039,7 +2075,7 @@ struct DNSQuestion_struct
domainname *qnameOrig; // Copy of the original question name if it is not fully qualified
mDNSQuestionCallback *QuestionCallback;
void *QuestionContext;
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
uDNSMetrics metrics; // Data used for collecting unicast DNS query metrics.
#endif
#if USE_DNS64
@@ -2155,7 +2191,7 @@ struct NetworkInterfaceInfo_struct
mDNSBool DirectLink; // a direct link, indicating we can skip the probe for
// address records
mDNSBool SupportsUnicastMDNSResponse; // Indicates that the interface supports unicast responses
- // to Bonjour queries. Generally true for an interface
+ // to Bonjour queries. Generally true for an interface.
};
#define SLE_DELETE 0x00000001
@@ -2604,6 +2640,8 @@ extern mDNSu8 NumUnreachableDNSServers;
#define mDNSinline static __inline
#elif ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
#define mDNSinline static inline
+#else
+ #define mDNSinline static inline
#endif
// If we're not doing inline functions, then this header needs to have the extern declarations
@@ -2778,7 +2816,7 @@ extern void mDNS_SetupResourceRecord(AuthRecord *rr, RData *RDataStorage, mDN
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,
- const domainname *const host, mDNSIPPort port, const mDNSu8 txtinfo[], mDNSu16 txtlen,
+ const domainname *const host, mDNSIPPort port, RData *txtrdata, const mDNSu8 txtinfo[], mDNSu16 txtlen,
AuthRecord *SubTypes, mDNSu32 NumSubTypes,
mDNSInterfaceID InterfaceID, mDNSServiceCallback Callback, void *Context, mDNSu32 flags);
extern mStatus mDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra, RData *rdata, mDNSu32 ttl, mDNSu32 flags);
@@ -2939,6 +2977,7 @@ extern char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RDataB
#define RRDisplayString(m, rr) GetRRDisplayString_rdb(rr, &(rr)->rdata->u, (m)->MsgBuffer)
#define ARDisplayString(m, rr) GetRRDisplayString_rdb(&(rr)->resrec, &(rr)->resrec.rdata->u, (m)->MsgBuffer)
#define CRDisplayString(m, rr) GetRRDisplayString_rdb(&(rr)->resrec, &(rr)->resrec.rdata->u, (m)->MsgBuffer)
+#define MortalityDisplayString(M) (M == Mortality_Mortal ? "mortal" : (M == Mortality_Immortal ? "immortal" : "ghost"))
extern mDNSBool mDNSSameAddress(const mDNSAddr *ip1, const mDNSAddr *ip2);
extern void IncrementLabelSuffix(domainlabel *name, mDNSBool RichText);
extern mDNSBool mDNSv4AddrIsRFC1918(const mDNSv4Addr * const addr); // returns true for RFC1918 private addresses
@@ -3039,8 +3078,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, mDNSBool isExpensive, mDNSu16 resGroupID,
- mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO);
+ const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSBool isCLAT46,
+ 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);
@@ -3357,7 +3396,7 @@ extern void RemoveAutoTunnel6Record(mDNS *const m);
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(NetworkInterfaceInfo *const intf, mDNSBool *keepaliveOnly);
+extern mStatus ActivateLocalProxy(NetworkInterfaceInfo *const intf, mDNSBool offloadKeepAlivesOnly, mDNSBool *keepaliveOnly);
extern void mDNSPlatformUpdateDNSStatus(DNSQuestion *q);
extern void mDNSPlatformTriggerDNSRetry(DNSQuestion *v4q, DNSQuestion *v6q);
extern void mDNSPlatformLogToFile(int log_level, const char *buffer);
@@ -3601,17 +3640,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) <= 912) ? 1 : -1];
+ char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 1168) ? 1 : -1];
- char sizecheck_ZoneData [(sizeof(ZoneData) <= 1744) ? 1 : -1];
+ char sizecheck_ZoneData [(sizeof(ZoneData) <= 2000) ? 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) <= 7376) ? 1 : -1];
+ char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 8400) ? 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) <= 1256) ? 1 : -1];
+ char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1512) ? 1 : -1];
#endif
};
diff --git a/usr/src/contrib/mDNSResponder/mDNSCore/uDNS.c b/usr/src/contrib/mDNSResponder/mDNSCore/uDNS.c
index 0b1fe638ec..84913404d4 100755
--- a/usr/src/contrib/mDNSResponder/mDNSCore/uDNS.c
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/uDNS.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2017 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,10 @@
#endif
#include "uDNS.h"
+#if AWD_METRICS
+#include "Metrics.h"
+#endif
+
#if (defined(_MSC_VER))
// Disable "assignment within conditional expression".
// Other compilers understand the convention that if you place the assignment expression within an extra pair
@@ -111,9 +115,11 @@ mDNSlocal void SetRecordRetry(mDNS *const m, AuthRecord *rr, mDNSu32 random)
#pragma mark - Name Server List Management
#endif
+#define TrueFalseStr(X) ((X) ? "true" : "false")
+
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, mDNSBool isExpensive, mDNSu16 resGroupID,
- mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO)
+ const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSBool isCLAT46,
+ mDNSu16 resGroupID, mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO)
{
DNSServer **p = &m->DNSServers;
DNSServer *tmp = mDNSNULL;
@@ -127,9 +133,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 isExpensive %s req_DO is %s",
- NumUnicastDNSServers, addr, d->c, interface, serviceID, scoped, resGroupID, reqA ? "True" : "False", reqAAAA ? "True" : "False",
- cellIntf ? "True" : "False", isExpensive ? "True" : "False", reqDO ? "True" : "False");
+ LogInfo("mDNS_AddDNSServer(%d): Adding %#a for %##s, InterfaceID %p, serviceID %u, scoped %d, resGroupID %d req_A %s, req_AAAA %s, cell %s, expensive %s, CLAT46 %s, req_DO %s",
+ NumUnicastDNSServers, addr, d->c, interface, serviceID, scoped, resGroupID,
+ TrueFalseStr(reqA), TrueFalseStr(reqAAAA), TrueFalseStr(cellIntf), TrueFalseStr(isExpensive), TrueFalseStr(isCLAT46), TrueFalseStr(reqDO));
while (*p) // Check if we already have this {interface,address,port,domain} tuple registered + reqA/reqAAAA bits
{
@@ -193,6 +199,7 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
(*p)->timeout = timeout;
(*p)->cellIntf = cellIntf;
(*p)->isExpensive = isExpensive;
+ (*p)->isCLAT46 = isCLAT46;
(*p)->req_A = reqA;
(*p)->req_AAAA = reqAAAA;
(*p)->req_DO = reqDO;
@@ -544,7 +551,7 @@ mDNSlocal mStatus uDNS_RequestAddress(mDNS *m)
return err;
}
-mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info, mDNSBool usePCP)
+mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info, mDNSBool usePCP, mDNSBool unmapping)
{
mStatus err = mStatus_NoError;
@@ -643,19 +650,25 @@ mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info, mDNSBool useP
info->sentNATPMP = mDNSfalse;
#ifdef _LEGACY_NAT_TRAVERSAL_
- if (mDNSIPPortIsZero(m->UPnPRouterPort) || mDNSIPPortIsZero(m->UPnPSOAPPort))
+ // If an unmapping is being performed, then don't send an LNT discovery message or an LNT port map request.
+ if (!unmapping)
{
- LNT_SendDiscoveryMsg(m);
- debugf("uDNS_SendNATMsg: LNT_SendDiscoveryMsg");
- }
- else
- {
- mStatus lnterr = LNT_MapPort(m, info);
- if (lnterr)
- LogMsg("uDNS_SendNATMsg: LNT_MapPort returned error %d", lnterr);
+ if (mDNSIPPortIsZero(m->UPnPRouterPort) || mDNSIPPortIsZero(m->UPnPSOAPPort))
+ {
+ LNT_SendDiscoveryMsg(m);
+ debugf("uDNS_SendNATMsg: LNT_SendDiscoveryMsg");
+ }
+ else
+ {
+ mStatus lnterr = LNT_MapPort(m, info);
+ if (lnterr)
+ LogMsg("uDNS_SendNATMsg: LNT_MapPort returned error %d", lnterr);
- err = err ? err : lnterr; // PCP error takes precedence
+ err = err ? err : lnterr; // PCP error takes precedence
+ }
}
+#else
+ (void)unmapping; // Unused
#endif // _LEGACY_NAT_TRAVERSAL_
}
}
@@ -919,6 +932,16 @@ mDNSexport mStatus mDNS_StopNATOperation_internal(mDNS *m, NATTraversalInfo *tra
}
}
+ // Even if we DIDN'T make a successful UPnP mapping yet, we might still have a partially-open TCP connection we need to clean up
+ // Before zeroing traversal->RequestedPort below, perform the LNT unmapping, which requires the mapping's external port,
+ // held by the traversal->RequestedPort variable.
+ #ifdef _LEGACY_NAT_TRAVERSAL_
+ {
+ mStatus err = LNT_UnmapPort(m, traversal);
+ if (err) LogMsg("Legacy NAT Traversal - unmap request failed with error %d", err);
+ }
+ #endif // _LEGACY_NAT_TRAVERSAL_
+
if (traversal->ExpiryTime && unmap)
{
traversal->NATLease = 0;
@@ -940,17 +963,9 @@ mDNSexport mStatus mDNS_StopNATOperation_internal(mDNS *m, NATTraversalInfo *tra
traversal->RequestedPort = zeroIPPort;
traversal->NewAddress = zerov4Addr;
- uDNS_SendNATMsg(m, traversal, traversal->lastSuccessfulProtocol != NATTProtocolNATPMP);
+ uDNS_SendNATMsg(m, traversal, traversal->lastSuccessfulProtocol != NATTProtocolNATPMP, mDNStrue);
}
- // Even if we DIDN'T make a successful UPnP mapping yet, we might still have a partially-open TCP connection we need to clean up
- #ifdef _LEGACY_NAT_TRAVERSAL_
- {
- mStatus err = LNT_UnmapPort(m, traversal);
- if (err) LogMsg("Legacy NAT Traversal - unmap request failed with error %d", err);
- }
- #endif // _LEGACY_NAT_TRAVERSAL_
-
return(mStatus_NoError);
}
@@ -1327,6 +1342,12 @@ mDNSlocal void tcpCallback(TCPSocket *sock, void *context, mDNSBool ConnectionEs
err = mDNSSendDNSMessage(m, &tcpInfo->request, end, mDNSInterface_Any, mDNSNULL, &tcpInfo->Addr, tcpInfo->Port, sock, AuthInfo, mDNSfalse);
if (err) { debugf("ERROR: tcpCallback: mDNSSendDNSMessage - %d", err); err = mStatus_UnknownErr; goto exit; }
+#if AWD_METRICS
+ if (mDNSSameIPPort(tcpInfo->Port, UnicastDNSPort))
+ {
+ MetricsUpdateDNSQuerySize((mDNSu32)(end - (mDNSu8 *)&tcpInfo->request));
+ }
+#endif
// Record time we sent this question
if (q)
@@ -1856,7 +1877,10 @@ mDNSlocal void GetZoneData_QuestionCallback(mDNS *const m, DNSQuestion *question
if (question->ThisQInterval != -1)
LogMsg("GetZoneData_QuestionCallback: Question %##s (%s) ThisQInterval %d not -1", question->qname.c, DNSTypeName(question->qtype), question->ThisQInterval);
zd->Addr.type = mDNSAddrType_IPv4;
- zd->Addr.ip.v4 = (answer->rdlength == 4) ? answer->rdata->u.ipv4 : zerov4Addr;
+ if (answer->rdlength == 4)
+ zd->Addr.ip.v4 = answer->rdata->u.ipv4;
+ else
+ zd->Addr.ip.v4 = zerov4Addr;
// In order to simulate firewalls blocking our outgoing TCP connections, returning immediate ICMP errors or TCP resets,
// the code below will make us try to connect to loopback, resulting in an immediate "port unreachable" failure.
// This helps us test to make sure we handle this case gracefully
@@ -2679,6 +2703,7 @@ mDNSexport void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn)
mDNSexport void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, const mDNSAddr *v6addr, const mDNSAddr *router)
{
mDNSBool v4Changed, v6Changed, RouterChanged;
+ mDNSv6Addr v6;
if (m->mDNS_busy != m->mDNS_reentrancy)
LogMsg("mDNS_SetPrimaryInterfaceInfo: mDNS_busy (%ld) != mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
@@ -2690,7 +2715,11 @@ mDNSexport void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, co
mDNS_Lock(m);
v4Changed = !mDNSSameIPv4Address(m->AdvertisedV4.ip.v4, v4addr ? v4addr->ip.v4 : zerov4Addr);
- v6Changed = !mDNSSameIPv6Address(m->AdvertisedV6.ip.v6, v6addr ? v6addr->ip.v6 : zerov6Addr);
+ if (v6addr)
+ v6 = v6addr->ip.v6;
+ else
+ v6 = zerov6Addr;
+ v6Changed = !mDNSSameIPv6Address(m->AdvertisedV6.ip.v6, v6);
RouterChanged = !mDNSSameIPv4Address(m->Router.ip.v4, router ? router->ip.v4 : zerov4Addr);
if (v4addr && (v4Changed || RouterChanged))
@@ -3649,7 +3678,7 @@ mDNSlocal void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID Interface
{
// Send a NAT-PMP request for this operation as needed
// and update the state variables
- uDNS_SendNATMsg(m, n, mDNSfalse);
+ uDNS_SendNATMsg(m, n, mDNSfalse, mDNSfalse);
}
m->NextScheduledNATOp = m->timenow;
@@ -3903,14 +3932,7 @@ mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNS
if (msg->h.flags.b[0] & kDNSFlag0_TC && mDNSSameOpaque16(qptr->TargetQID, msg->h.id) && m->timenow - qptr->LastQTime < RESPONSE_WINDOW)
{
if (!srcaddr) LogMsg("uDNS_ReceiveMsg: TCP DNS response had TC bit set: ignoring");
- else
- {
- // Don't reuse TCP connections. We might have failed over to a different DNS server
- // while the first TCP connection is in progress. We need a new TCP connection to the
- // new DNS server. So, always try to establish a new connection.
- if (qptr->tcp) { DisposeTCPConn(qptr->tcp); qptr->tcp = mDNSNULL; }
- qptr->tcp = MakeTCPConn(m, mDNSNULL, mDNSNULL, kTCPSocketFlags_Zero, srcaddr, srcport, mDNSNULL, qptr, mDNSNULL);
- }
+ else uDNS_RestartQuestionAsTCP(m, qptr, srcaddr, srcport);
}
}
@@ -4694,8 +4716,9 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
new = GetServerForQuestion(m, q);
if (new)
{
+ mDNSIPPort zp = zeroIPPort;
LogInfo("uDNS_checkCurrentQuestion: Retrying question %p %##s (%s) DNS Server %#a:%d ThisQInterval %d",
- q, q->qname.c, DNSTypeName(q->qtype), new ? &new->addr : mDNSNULL, mDNSVal16(new ? new->port : zeroIPPort), q->ThisQInterval);
+ q, q->qname.c, DNSTypeName(q->qtype), new ? &new->addr : mDNSNULL, mDNSVal16(new? new->port : zp), q->ThisQInterval);
DNSServerChangeForQuestion(m, q, new);
}
for (qptr = q->next ; qptr; qptr = qptr->next)
@@ -4730,6 +4753,7 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
}
else
{
+ mDNSIPPort zp = zeroIPPort;
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);
@@ -4757,9 +4781,10 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
else
{
err = mDNSSendDNSMessage(m, &m->omsg, end, q->qDNSServer->interface, q->LocalSocket, &q->qDNSServer->addr, q->qDNSServer->port, mDNSNULL, mDNSNULL, q->UseBackgroundTrafficClass);
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
if (!err)
{
+ MetricsUpdateDNSQuerySize((mDNSu32)(end - (mDNSu8 *)&m->omsg));
if (q->metrics.answered)
{
q->metrics.querySendCount = 0;
@@ -4891,9 +4916,12 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
q->qDNSServer = GetServerForQuestion(m, q);
for (qptr = q->next ; qptr; qptr = qptr->next)
if (qptr->DuplicateOf == q) { qptr->validDNSServers = q->validDNSServers; qptr->qDNSServer = q->qDNSServer; }
- LogInfo("uDNS_checkCurrentQuestion: Tried all DNS servers, retry question %p SuppressUnusable %d %##s (%s) with DNS Server %#a:%d after 60 seconds, ThisQInterval %d",
+ {
+ mDNSIPPort zp = zeroIPPort;
+ LogInfo("uDNS_checkCurrentQuestion: Tried all DNS servers, retry question %p SuppressUnusable %d %##s (%s) with DNS Server %#a:%d after 60 seconds, ThisQInterval %d",
q, q->SuppressUnusable, q->qname.c, DNSTypeName(q->qtype),
- q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL, mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zeroIPPort), q->ThisQInterval);
+ q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL, mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zp), q->ThisQInterval);
+ }
}
}
else
@@ -4991,7 +5019,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
cur->retryInterval = NATMAP_INIT_RETRY;
}
- uDNS_SendNATMsg(m, cur, mDNStrue); // Will also do UPnP discovery for us, if necessary
+ uDNS_SendNATMsg(m, cur, mDNStrue, mDNSfalse); // Will also do UPnP discovery for us, if necessary
if (cur->ExpiryTime) // If have active mapping then set next renewal time halfway to expiry
NATSetNextRenewalTime(m, cur);
@@ -5722,6 +5750,15 @@ mDNSexport domainname *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mD
return mDNSNULL;
}
+mDNSexport void uDNS_RestartQuestionAsTCP(mDNS *m, DNSQuestion *const q, const mDNSAddr *const srcaddr, const mDNSIPPort srcport)
+{
+ // Don't reuse TCP connections. We might have failed over to a different DNS server
+ // while the first TCP connection is in progress. We need a new TCP connection to the
+ // new DNS server. So, always try to establish a new connection.
+ if (q->tcp) { DisposeTCPConn(q->tcp); q->tcp = mDNSNULL; }
+ q->tcp = MakeTCPConn(m, mDNSNULL, mDNSNULL, kTCPSocketFlags_Zero, srcaddr, srcport, mDNSNULL, q, mDNSNULL);
+}
+
mDNSlocal void FlushAddressCacheRecords(mDNS *const m)
{
mDNSu32 slot;
@@ -5787,7 +5824,7 @@ struct CompileTimeAssertionChecks_uDNS
// other overly-large structures instead of having a pointer to them, can inadvertently
// cause structure sizes (and therefore memory usage) to balloon unreasonably.
char sizecheck_tcpInfo_t [(sizeof(tcpInfo_t) <= 9056) ? 1 : -1];
- char sizecheck_SearchListElem[(sizeof(SearchListElem) <= 5000) ? 1 : -1];
+ char sizecheck_SearchListElem[(sizeof(SearchListElem) <= 6136) ? 1 : -1];
};
#if COMPILER_LIKES_PRAGMA_MARK
diff --git a/usr/src/contrib/mDNSResponder/mDNSCore/uDNS.h b/usr/src/contrib/mDNSResponder/mDNSCore/uDNS.h
index 90f50a6fc1..0a0622784d 100755
--- a/usr/src/contrib/mDNSResponder/mDNSCore/uDNS.h
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/uDNS.h
@@ -129,6 +129,8 @@ 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(mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal);
+
+extern void uDNS_RestartQuestionAsTCP(mDNS *m, DNSQuestion *const q, const mDNSAddr *const srcaddr, const mDNSIPPort srcport);
typedef enum
{
diff --git a/usr/src/contrib/mDNSResponder/mDNSPosix/PosixDaemon.c b/usr/src/contrib/mDNSResponder/mDNSPosix/PosixDaemon.c
index c1cc6a4e65..dd932949e7 100644
--- a/usr/src/contrib/mDNSResponder/mDNSPosix/PosixDaemon.c
+++ b/usr/src/contrib/mDNSResponder/mDNSPosix/PosixDaemon.c
@@ -132,8 +132,8 @@ mDNSlocal void ToggleLogPacket(void)
mDNS_PacketLoggingEnabled = !mDNS_PacketLoggingEnabled;
}
-mDNSlocal void DumpStateLog()
// Dump a little log of what we've been up to.
+mDNSlocal void DumpStateLog()
{
LogMsg("---- BEGIN STATE LOG ----");
udsserver_info();
diff --git a/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSPosix.c b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSPosix.c
index b9c3cd58eb..50acd2bd4c 100755
--- a/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSPosix.c
+++ b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSPosix.c
@@ -433,10 +433,6 @@ mDNSexport void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result
#pragma mark ***** DDNS Config Platform Functions
#endif
-/*
- * Stub to set or get DNS config. Even if it actually does not do anything,
- * it has to make sure the data is zeroed properly.
- */
mDNSexport mDNSBool mDNSPlatformSetDNSConfig(mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
DNameListElem **BrowseDomains, mDNSBool ackConfig)
{
@@ -506,7 +502,7 @@ mDNSexport int ParseDNSServers(mDNS *m, const char *filePath)
mDNSAddr DNSAddr;
DNSAddr.type = mDNSAddrType_IPv4;
DNSAddr.ip.v4.NotAnInteger = ina.s_addr;
- mDNS_AddDNSServer(m, NULL, mDNSInterface_Any, 0, &DNSAddr, UnicastDNSPort, kScopeNone, 0, mDNSfalse, mDNSfalse, 0, mDNStrue, mDNStrue, mDNSfalse);
+ mDNS_AddDNSServer(m, NULL, mDNSInterface_Any, 0, &DNSAddr, UnicastDNSPort, kScopeNone, 0, mDNSfalse, mDNSfalse, mDNSfalse, 0, mDNStrue, mDNStrue, mDNSfalse);
numOfServers++;
}
}
@@ -667,9 +663,9 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
// Enable inbound packets on IFEF_AWDL interface.
// Only done for multicast sockets, since we don't expect unicast socket operations
// on the IFEF_AWDL interface. Operation is a no-op for other interface types.
- #ifdef SO_RECV_ANYIF
+ #ifdef SO_RECV_ANYIF
if (setsockopt(*sktPtr, SOL_SOCKET, SO_RECV_ANYIF, &kOn, sizeof(kOn)) < 0) perror("setsockopt - SO_RECV_ANYIF");
- #endif
+ #endif
}
// We want to receive destination addresses and interface identifiers.
@@ -771,11 +767,11 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
#warning This platform has no way to get the destination interface information for IPv6 -- will only work for single-homed hosts
#endif
#if defined(IPV6_RECVHOPLIMIT)
- if (err == 0)
- {
- err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &kOn, sizeof(kOn));
- if (err < 0) { err = errno; perror("setsockopt - IPV6_RECVHOPLIMIT"); }
- }
+ if (err == 0)
+ {
+ err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &kOn, sizeof(kOn));
+ if (err < 0) { err = errno; perror("setsockopt - IPV6_RECVHOPLIMIT"); }
+ }
#elif defined(IPV6_HOPLIMIT)
if (err == 0)
{
@@ -1220,10 +1216,10 @@ mDNSlocal mDNSu32 ProcessRoutingNotification(int sd)
*/
case RTM_ADD:
case RTM_DELETE:
- if (pRSMsg->ifam_type == RTM_IFINFO)
- result |= 1 << ((struct if_msghdr*) pRSMsg)->ifm_index;
- else
- result |= 1 << pRSMsg->ifam_index;
+ if (pRSMsg->ifam_type == RTM_IFINFO)
+ result |= 1 << ((struct if_msghdr*) pRSMsg)->ifm_index;
+ else
+ result |= 1 << pRSMsg->ifam_index;
break;
}
@@ -1341,7 +1337,8 @@ mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
// Failure to observe interface changes is non-fatal.
if (err != mStatus_NoError)
{
- fprintf(stderr, "mDNS(%d) WARNING: Unable to detect interface changes (%d).\n", getpid(), err);
+ fprintf(stderr, "mDNS(%d) WARNING: Unable to detect interface changes (%d).\n",
+ (int)getpid(), err);
err = mStatus_NoError;
}
}
diff --git a/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.c b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.c
index ed6da80953..cc2401bdac 100755
--- a/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.c
+++ b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2018 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -84,40 +84,56 @@ void plen_to_mask(int plen, char *addr) {
}
/* Gets IPv6 interface information from the /proc filesystem in linux*/
-struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
+struct ifi_info *get_ifi_info_linuxv6(int doaliases)
{
struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
FILE *fp = NULL;
- char addr[8][5];
- int flags, myflags, index, plen, scope;
- char ifname[9], lastname[IFNAMSIZ];
- char addr6[32+7+1]; /* don't forget the seven ':' */
+ int i, nitems, flags, index, plen, scope;
struct addrinfo hints, *res0;
int err;
int sockfd = -1;
struct ifreq ifr;
+ char ifnameFmt[16], addrStr[32 + 7 + 1], ifname[IFNAMSIZ], lastname[IFNAMSIZ];
res0=NULL;
ifihead = NULL;
ifipnext = &ifihead;
- lastname[0] = 0;
if ((fp = fopen(PROC_IFINET6_PATH, "r")) != NULL) {
sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
if (sockfd < 0) {
goto gotError;
}
- while (fscanf(fp,
- "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %8s\n",
- addr[0],addr[1],addr[2],addr[3],
- addr[4],addr[5],addr[6],addr[7],
- &index, &plen, &scope, &flags, ifname) != EOF) {
-
- myflags = 0;
- if (strncmp(lastname, ifname, IFNAMSIZ) == 0) {
+
+ // Parse /proc/net/if_inet6 according to <https://www.tldp.org/HOWTO/Linux+IPv6-HOWTO/ch11s04.html>.
+
+ // Create a string specifier with a width of IFNAMSIZ - 1 ("%<IFNAMSIZ - 1>s") to scan the interface name. The
+ // reason why we don't just use the string-ified macro expansion of IFNAMSIZ for the width is because the width
+ // needs to be a decimal string and there's no guarantee that IFNAMSIZ will be defined as a decimal integer. For
+ // example, it could be defined in hexadecimal or as an arithmetic expression.
+
+ snprintf(ifnameFmt, sizeof(ifnameFmt), "%%%ds", IFNAMSIZ - 1);
+
+ // Write the seven IPv6 address string colons and NUL terminator, i.e., "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx".
+ // The remaining 32 IPv6 address characters come from /proc/net/if_inet6.
+
+ for (i = 4; i < 39; i += 5) addrStr[i] = ':';
+ addrStr[39] = '\0';
+
+ lastname[0] = '\0';
+ for (;;) {
+ nitems = fscanf(fp, " %4c%4c%4c%4c%4c%4c%4c%4c %x %x %x %x",
+ &addrStr[0], &addrStr[5], &addrStr[10], &addrStr[15],
+ &addrStr[20], &addrStr[25], &addrStr[30], &addrStr[35],
+ &index, &plen, &scope, &flags);
+ if (nitems != 12) break;
+
+ nitems = fscanf(fp, ifnameFmt, ifname);
+ if (nitems != 1) break;
+
+ if (strcmp(lastname, ifname) == 0) {
if (doaliases == 0)
continue; /* already processed this interface */
- myflags = IFI_ALIAS;
}
memcpy(lastname, ifname, IFNAMSIZ);
ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
@@ -130,15 +146,11 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
*ifipnext = ifi; /* prev points to this new one */
ifipnext = &ifi->ifi_next; /* pointer to next one goes here */
- sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
- addr[0],addr[1],addr[2],addr[3],
- addr[4],addr[5],addr[6],addr[7]);
-
/* Add address of the interface */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_flags = AI_NUMERICHOST;
- err = getaddrinfo(addr6, NULL, &hints, &res0);
+ err = getaddrinfo(addrStr, NULL, &hints, &res0);
if (err) {
goto gotError;
}
@@ -156,9 +168,9 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
goto gotError;
}
- ((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_family=family;
+ ((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_family=AF_INET6;
((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_scope_id=scope;
- inet_pton(family, ipv6addr, &((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_addr);
+ inet_pton(AF_INET6, ipv6addr, &((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_addr);
/* Add interface name */
memcpy(ifi->ifi_name, ifname, IFI_NAME);
@@ -222,8 +234,7 @@ done:
* Unlike plen_to_mask returns netmask in binary form and not
* in text form.
*/
-static void plen_to_netmask(int prefix, unsigned char *addr)
-{
+static void plen_to_netmask(int prefix, unsigned char *addr) {
for (; prefix > 8; prefix -= 8)
*addr++ = 0xff;
for (; prefix > 0; prefix--)
@@ -543,7 +554,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
#endif
#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
- if (family == AF_INET6) return get_ifi_info_linuxv6(family, doaliases);
+ if (family == AF_INET6) return get_ifi_info_linuxv6(doaliases);
#elif HAVE_SOLARIS
return get_ifi_info_solaris(family);
#endif
@@ -839,7 +850,7 @@ recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
*ttl = 255; // If kernel fails to provide TTL data then assume the TTL was 255 as it should be
- msg.msg_control = control_un.control;
+ msg.msg_control = (void *) control_un.control;
msg.msg_controllen = sizeof(control_un.control);
msg.msg_flags = 0;
#else
diff --git a/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.h b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.h
index cc81b7d393..2b36ceb042 100755
--- a/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.h
+++ b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2018 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -62,8 +62,8 @@ typedef unsigned int socklen_t;
#define GET_SA_LEN(X) (((struct sockaddr*)&(X))->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr))
#endif
-#define IFI_NAME 16 /* same as IFNAMSIZ in <net/if.h> */
-#define IFI_HADDR 8 /* allow for 64-bit EUI-64 in future */
+#define IFI_NAME IFNAMSIZ /* same as IFNAMSIZ in <net/if.h> */
+#define IFI_HADDR 8 /* allow for 64-bit EUI-64 in future */
// Renamed from my_in_pktinfo because in_pktinfo is used by Linux.
@@ -98,7 +98,7 @@ struct ifi_info {
#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
#define PROC_IFINET6_PATH "/proc/net/if_inet6"
-extern struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases);
+extern struct ifi_info *get_ifi_info_linuxv6(int doaliases);
#endif
#if defined(AF_INET6) && HAVE_IPV6
diff --git a/usr/src/contrib/mDNSResponder/mDNSShared/PlatformCommon.c b/usr/src/contrib/mDNSResponder/mDNSShared/PlatformCommon.c
index 909efed5c5..3a13d5ce53 100644
--- a/usr/src/contrib/mDNSResponder/mDNSShared/PlatformCommon.c
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/PlatformCommon.c
@@ -69,10 +69,9 @@ mDNSexport void mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAdd
else return;
if ((connect(sock, &addr.s, inner_len)) < 0) {
- if (errno != ENETUNREACH) {
- LogMsg("mDNSPlatformSourceAddrForDest: connect %#a failed errno %d "
- "(%s)", dst, errno, strerror(errno));
- }
+ if (errno != ENETUNREACH)
+ LogMsg("mDNSPlatformSourceAddrForDest: connect %#a failed errno %d (%s)", dst, errno,
+ strerror(errno));
goto exit;
}
diff --git a/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd.h b/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd.h
index 701c4ff3a6..0a4597fae0 100644
--- a/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd.h
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2003-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -66,7 +66,7 @@
*/
#ifndef _DNS_SD_H
-#define _DNS_SD_H 8780101
+#define _DNS_SD_H 8806001
#ifdef __cplusplus
extern "C" {
@@ -75,9 +75,11 @@ extern "C" {
/* Set to 1 if libdispatch is supported
* Note: May also be set by project and/or Makefile
*/
-#ifndef _DNS_SD_LIBDISPATCH
+#if defined(__APPLE__)
+#define _DNS_SD_LIBDISPATCH 1
+#else
#define _DNS_SD_LIBDISPATCH 0
-#endif /* ndef _DNS_SD_LIBDISPATCH */
+#endif
/* standard calling convention under Win32 is __stdcall */
/* Note: When compiling Intel EFI (Extensible Firmware Interface) under MS Visual Studio, the */
@@ -88,6 +90,12 @@ extern "C" {
#define DNSSD_API
#endif
+#if (defined(__GNUC__) && (__GNUC__ >= 4))
+#define DNSSD_EXPORT __attribute__((visibility("default")))
+#else
+#define DNSSD_EXPORT
+#endif
+
#if defined(_WIN32)
#include <winsock2.h>
typedef SOCKET dnssd_sock_t;
@@ -526,11 +534,25 @@ enum
* This flag is private and should not be used.
*/
- kDNSServiceFlagsPrivateFour = 0x40000000
+ kDNSServiceFlagsPrivateFour = 0x40000000,
/*
* This flag is private and should not be used.
*/
+ kDNSServiceFlagsAllowExpiredAnswers = 0x80000000,
+ /*
+ * When kDNSServiceFlagsAllowExpiredAnswers is passed to DNSServiceQueryRecord or DNSServiceGetAddrInfo,
+ * if there are matching expired records still in the cache, then they are immediately returned to the
+ * client, and in parallel a network query for that name is issued. All returned records from the query will
+ * remain in the cache after expiration.
+ */
+
+ kDNSServiceFlagsExpiredAnswer = 0x80000000
+ /*
+ * When kDNSServiceFlagsAllowExpiredAnswers is passed to DNSServiceQueryRecord or DNSServiceGetAddrInfo,
+ * an expired answer will have this flag set.
+ */
+
};
#define kDNSServiceOutputFlags (kDNSServiceFlagsValidate | kDNSServiceFlagsValidateOptional | kDNSServiceFlagsMoreComing | kDNSServiceFlagsAdd | kDNSServiceFlagsDefault)
@@ -871,6 +893,7 @@ typedef int32_t DNSServiceErrorType;
* if the daemon (or "system service" on Windows) is not running.
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceGetProperty
(
const char *property, /* Requested property (i.e. kDNSServiceProperty_DaemonVersion) */
@@ -930,6 +953,7 @@ DNSServiceErrorType DNSSD_API DNSServiceGetProperty
* error.
*/
+DNSSD_EXPORT
dnssd_sock_t DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef);
@@ -951,6 +975,7 @@ dnssd_sock_t DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef);
* an error code indicating the specific failure that occurred.
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef);
@@ -978,6 +1003,7 @@ DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef);
*
*/
+DNSSD_EXPORT
void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef);
@@ -1062,6 +1088,7 @@ typedef void (DNSSD_API *DNSServiceDomainEnumReply)
* is not initialized).
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
(
DNSServiceRef *sdRef,
@@ -1252,6 +1279,7 @@ typedef void (DNSSD_API *DNSServiceRegisterReply)
* is not initialized).
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceRegister
(
DNSServiceRef *sdRef,
@@ -1307,6 +1335,7 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister
* error code indicating the error that occurred (the RecordRef is not initialized).
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceAddRecord
(
DNSServiceRef sdRef,
@@ -1348,6 +1377,7 @@ DNSServiceErrorType DNSSD_API DNSServiceAddRecord
* error code indicating the error that occurred.
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
(
DNSServiceRef sdRef,
@@ -1380,6 +1410,7 @@ DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
* error code indicating the error that occurred.
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
(
DNSServiceRef sdRef,
@@ -1485,6 +1516,7 @@ typedef void (DNSSD_API *DNSServiceBrowseReply)
* is not initialized).
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceBrowse
(
DNSServiceRef *sdRef,
@@ -1613,6 +1645,7 @@ typedef void (DNSSD_API *DNSServiceResolveReply)
* is not initialized).
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceResolve
(
DNSServiceRef *sdRef,
@@ -1730,6 +1763,7 @@ typedef void (DNSSD_API *DNSServiceQueryRecordReply)
* is not initialized).
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
(
DNSServiceRef *sdRef,
@@ -1834,6 +1868,7 @@ typedef void (DNSSD_API *DNSServiceGetAddrInfoReply)
* the error that occurred.
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo
(
DNSServiceRef *sdRef,
@@ -1870,6 +1905,7 @@ DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo
* case the DNSServiceRef is not initialized).
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef);
/* DNSServiceRegisterRecord
@@ -1952,6 +1988,7 @@ typedef void (DNSSD_API *DNSServiceRegisterRecordReply)
* not initialized).
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
(
DNSServiceRef sdRef,
@@ -2001,6 +2038,7 @@ DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
*
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
(
DNSServiceFlags flags,
@@ -2184,6 +2222,7 @@ typedef void (DNSSD_API *DNSServiceNATPortMappingReply)
* display) then pass zero for protocol, internalPort, externalPort and ttl.
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceNATPortMappingCreate
(
DNSServiceRef *sdRef,
@@ -2230,6 +2269,7 @@ DNSServiceErrorType DNSSD_API DNSServiceNATPortMappingCreate
*
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceConstructFullName
(
char * const fullName,
@@ -2310,6 +2350,7 @@ typedef union _TXTRecordRef_t { char PrivateData[16]; char *ForceNaturalAlignmen
* the TXTRecordRef.
*/
+DNSSD_EXPORT
void DNSSD_API TXTRecordCreate
(
TXTRecordRef *txtRecord,
@@ -2328,6 +2369,7 @@ void DNSSD_API TXTRecordCreate
*
*/
+DNSSD_EXPORT
void DNSSD_API TXTRecordDeallocate
(
TXTRecordRef *txtRecord
@@ -2371,6 +2413,7 @@ void DNSSD_API TXTRecordDeallocate
* exceed the available storage.
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API TXTRecordSetValue
(
TXTRecordRef *txtRecord,
@@ -2394,6 +2437,7 @@ DNSServiceErrorType DNSSD_API TXTRecordSetValue
* exist in the TXTRecordRef.
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
(
TXTRecordRef *txtRecord,
@@ -2413,6 +2457,7 @@ DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
* Returns 0 if the TXTRecordRef is empty.
*/
+DNSSD_EXPORT
uint16_t DNSSD_API TXTRecordGetLength
(
const TXTRecordRef *txtRecord
@@ -2430,6 +2475,7 @@ uint16_t DNSSD_API TXTRecordGetLength
* to DNSServiceUpdateRecord().
*/
+DNSSD_EXPORT
const void * DNSSD_API TXTRecordGetBytesPtr
(
const TXTRecordRef *txtRecord
@@ -2484,6 +2530,7 @@ const void * DNSSD_API TXTRecordGetBytesPtr
* Otherwise, it returns 0.
*/
+DNSSD_EXPORT
int DNSSD_API TXTRecordContainsKey
(
uint16_t txtLen,
@@ -2513,6 +2560,7 @@ int DNSSD_API TXTRecordContainsKey
* For non-empty value, valueLen will be length of value data.
*/
+DNSSD_EXPORT
const void * DNSSD_API TXTRecordGetValuePtr
(
uint16_t txtLen,
@@ -2535,6 +2583,7 @@ const void * DNSSD_API TXTRecordGetValuePtr
*
*/
+DNSSD_EXPORT
uint16_t DNSSD_API TXTRecordGetCount
(
uint16_t txtLen,
@@ -2580,6 +2629,7 @@ uint16_t DNSSD_API TXTRecordGetCount
* TXTRecordGetCount()-1.
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
(
uint16_t txtLen,
@@ -2632,6 +2682,7 @@ DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
* queue param is invalid
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceSetDispatchQueue
(
DNSServiceRef service,
@@ -2646,6 +2697,7 @@ typedef void (DNSSD_API *DNSServiceSleepKeepaliveReply)
DNSServiceErrorType errorCode,
void *context
);
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceSleepKeepalive
(
DNSServiceRef *sdRef,
diff --git a/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_private.h b/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_private.h
index ccec1403d0..2d42973361 100644
--- a/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_private.h
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_private.h
@@ -1,11 +1,12 @@
/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2015 Apple Inc. All rights reserved.
+ *
+ * Copyright (c) 2015-2018 Apple Inc. All rights reserved.
*/
#ifndef _DNS_SD_PRIVATE_H
#define _DNS_SD_PRIVATE_H
+#include <dns_sd.h>
// Private flags (kDNSServiceFlagsPrivateOne, kDNSServiceFlagsPrivateTwo, kDNSServiceFlagsPrivateThree, kDNSServiceFlagsPrivateFour) from dns_sd.h
enum
@@ -58,6 +59,7 @@ enum
* returned to indicate that the calling process does not have entitlements
* to use this API.
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *sdRef, int32_t pid, uuid_t uuid);
#endif
@@ -77,12 +79,16 @@ DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *
* if the daemon is not running. The value of the pid is undefined if the return
* value has error.
*/
+DNSSD_EXPORT
DNSServiceErrorType DNSSD_API DNSServiceGetPID
(
uint16_t srcport,
int32_t *pid
);
+DNSSD_EXPORT
+DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain);
+
#define kDNSServiceCompPrivateDNS "PrivateDNS"
#define kDNSServiceCompMulticastDNS "MulticastDNS"
diff --git a/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientlib.c b/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientlib.c
index 649d403f02..1b4c5f8a54 100644
--- a/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientlib.c
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientlib.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2004-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -31,10 +31,6 @@
#include "dns_sd.h"
-#if MDNS_BUILDINGSHAREDLIBRARY || MDNS_BUILDINGSTUBLIBRARY
-#pragma export on
-#endif
-
#if defined(_WIN32)
// disable warning "conversion from <data> to uint16_t"
#pragma warning(disable:4244)
@@ -361,10 +357,18 @@ DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) # s
#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
+// The "used" variable attribute prevents a non-exported variable from being stripped, even if its visibility is hidden,
+// e.g., when compiling with -fvisibility=hidden.
+#if defined(__GNUC__)
+#define DNSSD_USED __attribute__((used))
+#else
+#define DNSSD_USED
+#endif
+
// NOT static -- otherwise the compiler may optimize it out
// The "@(#) " pattern is a special prefix the "what" command looks for
#ifndef MDNS_VERSIONSTR_NODTS
-const char VersionString_SCCS_libdnssd[] = "@(#) libdns_sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
+const char VersionString_SCCS_libdnssd[] DNSSD_USED = "@(#) libdns_sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
#else
const char VersionString_SCCS_libdnssd[] = "@(#) libdns_sd " STRINGIFY(mDNSResponderVersion);
#endif
diff --git a/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientstub.c b/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientstub.c
index e943c47f80..189c9361fa 100644
--- a/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientstub.c
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientstub.c
@@ -28,6 +28,7 @@
#include <errno.h>
#include <stdlib.h>
+#include <fcntl.h>
#include "dnssd_ipc.h"
@@ -80,7 +81,7 @@ static void syslog( int priority, const char * message, ...)
}
#else
- #include <fcntl.h> // For O_RDWR etc.
+ #include <sys/fcntl.h> // For O_RDWR etc.
#include <sys/time.h>
#include <sys/socket.h>
#include <syslog.h>
@@ -628,7 +629,7 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
}
#define deliver_request_bailout(MSG) \
- do { syslog(LOG_WARNING, "dnssd_clientstub deliver_request: %s failed %d (%s)", (MSG), dnssd_errno, dnssd_strerror(dnssd_errno)); goto cleanup; } while(0)
+ syslog(LOG_WARNING, "dnssd_clientstub deliver_request: %s failed %d (%s)", (MSG), dnssd_errno, dnssd_strerror(dnssd_errno)); goto cleanup
static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
{
@@ -674,14 +675,22 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
dnssd_sockaddr_t caddr;
dnssd_socklen_t len = (dnssd_socklen_t) sizeof(caddr);
listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
- if (!dnssd_SocketValid(listenfd)) deliver_request_bailout("TCP socket");
+ if (!dnssd_SocketValid(listenfd)) {
+ deliver_request_bailout("TCP socket");
+ }
caddr.sin_family = AF_INET;
caddr.sin_port = 0;
caddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
- if (bind(listenfd, (struct sockaddr*) &caddr, sizeof(caddr)) < 0) deliver_request_bailout("TCP bind");
- if (getsockname(listenfd, (struct sockaddr*) &caddr, &len) < 0) deliver_request_bailout("TCP getsockname");
- if (listen(listenfd, 1) < 0) deliver_request_bailout("TCP listen");
+ if (bind(listenfd, (struct sockaddr*) &caddr, sizeof(caddr)) < 0) {
+ deliver_request_bailout("TCP bind");
+ }
+ if (getsockname(listenfd, (struct sockaddr*) &caddr, &len) < 0) {
+ deliver_request_bailout("TCP getsockname");
+ }
+ if (listen(listenfd, 1) < 0) {
+ deliver_request_bailout("TCP listen");
+ }
port.s = caddr.sin_port;
data[0] = port.b[0]; // don't switch the byte order, as the
data[1] = port.b[1]; // daemon expects it in network byte order
@@ -692,7 +701,9 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
int bindresult;
dnssd_sockaddr_t caddr;
listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
- if (!dnssd_SocketValid(listenfd)) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET socket");
+ if (!dnssd_SocketValid(listenfd)) {
+ deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET socket");
+ }
caddr.sun_family = AF_LOCAL;
// According to Stevens (section 3.2), there is no portable way to
@@ -704,13 +715,19 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
mask = umask(0);
bindresult = bind(listenfd, (struct sockaddr *)&caddr, sizeof(caddr));
umask(mask);
- if (bindresult < 0) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET bind");
- if (listen(listenfd, 1) < 0) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET listen");
+ if (bindresult < 0) {
+ deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET bind");
+ }
+ if (listen(listenfd, 1) < 0) {
+ deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET listen");
+ }
}
#else
{
dnssd_sock_t sp[2];
- if (socketpair(AF_DNSSD, SOCK_STREAM, 0, sp) < 0) deliver_request_bailout("socketpair");
+ if (socketpair(AF_DNSSD, SOCK_STREAM, 0, sp) < 0) {
+ deliver_request_bailout("socketpair");
+ }
else
{
errsd = sp[0]; // We'll read our four-byte error code from sp[0]
@@ -776,8 +793,9 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
if ((err = set_waitlimit(listenfd, DNSSD_CLIENT_TIMEOUT)) != kDNSServiceErr_NoError)
goto cleanup;
errsd = accept(listenfd, (struct sockaddr *)&daddr, &len);
- if (!dnssd_SocketValid(errsd))
+ if (!dnssd_SocketValid(errsd)) {
deliver_request_bailout("accept");
+ }
#else
struct iovec vec = { ((char *)hdr) + sizeof(ipc_msg_hdr) + datalen, 1 }; // Send the last byte along with the SCM_RIGHTS
@@ -1330,7 +1348,7 @@ DNSServiceErrorType DNSSD_API DNSServiceResolve
if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
flags |= kDNSServiceFlagsIncludeP2P;
- err = ConnectToServer(sdRef, flags, resolve_request, handle_resolve_response, callBack, context);
+ err = ConnectToServer(sdRef, flags, resolve_request, handle_resolve_response, (void *)callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
// Calculate total message length
@@ -1396,7 +1414,7 @@ DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
flags |= kDNSServiceFlagsIncludeP2P;
- err = ConnectToServer(sdRef, flags, query_request, handle_query_response, callBack, context);
+ err = ConnectToServer(sdRef, flags, query_request, handle_query_response, (void *)callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
if (!name) name = "\0";
@@ -1504,7 +1522,7 @@ DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo
if (!sdRef || !hostname || !callBack) return kDNSServiceErr_BadParam;
- err = ConnectToServer(sdRef, flags, addrinfo_request, handle_addrinfo_response, callBack, context);
+ err = ConnectToServer(sdRef, flags, addrinfo_request, handle_addrinfo_response, (void *)callBack, context);
if (err)
{
return err; // On error ConnectToServer leaves *sdRef set to NULL
@@ -1562,7 +1580,7 @@ DNSServiceErrorType DNSSD_API DNSServiceBrowse
if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
flags |= kDNSServiceFlagsIncludeP2P;
- err = ConnectToServer(sdRef, flags, browse_request, handle_browse_response, callBack, context);
+ err = ConnectToServer(sdRef, flags, browse_request, handle_browse_response, (void *)callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
if (!domain) domain = "";
@@ -1584,7 +1602,6 @@ DNSServiceErrorType DNSSD_API DNSServiceBrowse
return err;
}
-DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain);
DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain)
{
DNSServiceErrorType err;
@@ -1654,7 +1671,7 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister
if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
flags |= kDNSServiceFlagsIncludeP2P;
- err = ConnectToServer(sdRef, flags, reg_service_request, callBack ? handle_regservice_response : NULL, callBack, context);
+ err = ConnectToServer(sdRef, flags, reg_service_request, callBack ? handle_regservice_response : NULL, (void *)callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
len = sizeof(DNSServiceFlags);
@@ -1714,7 +1731,7 @@ DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
f2 = (flags & kDNSServiceFlagsRegistrationDomains) != 0;
if (f1 + f2 != 1) return kDNSServiceErr_BadParam;
- err = ConnectToServer(sdRef, flags, enumeration_request, handle_enumeration_response, callBack, context);
+ err = ConnectToServer(sdRef, flags, enumeration_request, handle_enumeration_response, (void *)callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
len = sizeof(DNSServiceFlags);
@@ -2211,7 +2228,7 @@ DNSServiceErrorType DNSSD_API DNSServiceNATPortMappingCreate
union { uint16_t s; u_char b[2]; } internalPort = { internalPortInNetworkByteOrder };
union { uint16_t s; u_char b[2]; } externalPort = { externalPortInNetworkByteOrder };
- DNSServiceErrorType err = ConnectToServer(sdRef, flags, port_mapping_request, handle_port_mapping_response, callBack, context);
+ DNSServiceErrorType err = ConnectToServer(sdRef, flags, port_mapping_request, handle_port_mapping_response, (void *)callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
len = sizeof(flags);
@@ -2413,7 +2430,7 @@ DNSServiceErrorType DNSSD_API DNSServiceSleepKeepalive
ka = malloc(sizeof(SleepKAContext));
if (!ka) return kDNSServiceErr_NoMemory;
- ka->AppCallback = callBack;
+ ka->AppCallback = (void *)callBack;
ka->AppContext = context;
err = DNSServiceCreateConnection(sdRef);
diff --git a/usr/src/contrib/mDNSResponder/mDNSShared/mDNSDebug.c b/usr/src/contrib/mDNSResponder/mDNSShared/mDNSDebug.c
index 3f78384c81..e76ae419bb 100644
--- a/usr/src/contrib/mDNSResponder/mDNSShared/mDNSDebug.c
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/mDNSDebug.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2003-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2018 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -77,6 +77,7 @@ void LogMsg_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_MSG)
void LogOperation_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_OPERATION)
void LogSPS_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_SPS)
void LogInfo_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_INFO)
+void LogDebug_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_DEBUG)
#endif
#if MDNS_DEBUGMSGS
diff --git a/usr/src/contrib/mDNSResponder/mDNSShared/uds_daemon.c b/usr/src/contrib/mDNSResponder/mDNSShared/uds_daemon.c
index de30ef13a1..35b65f6608 100644
--- a/usr/src/contrib/mDNSResponder/mDNSShared/uds_daemon.c
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/uds_daemon.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2003-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2018 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,9 @@
// not fully qualified) with any number of labels e.g., moon, moon.cs, moon.cs.be, etc.
mDNSBool AlwaysAppendSearchDomains = mDNSfalse;
+// Control enabling ioptimistic DNS
+mDNSBool EnableAllowExpired = mDNStrue;
+
// Apple-specific functionality, not required for other platforms
#if APPLE_OSX_mDNSResponder
#include <sys/ucred.h>
@@ -325,8 +328,8 @@ mDNSlocal void abort_request(request_state *req)
// Now, if this request_state is not subordinate to some other primary, close file descriptor and discard replies
if (!req->primary)
{
- if (req->errsd != req->sd) LogOperation("%3d: Removing FD and closing errsd %d", req->sd, req->errsd);
- else LogOperation("%3d: Removing FD", req->sd);
+ if (req->errsd != req->sd) LogDebug("%3d: Removing FD and closing errsd %d", req->sd, req->errsd);
+ else LogDebug("%3d: Removing FD", req->sd);
udsSupportRemoveFDFromEventLoop(req->sd, req->platform_data); // Note: This also closes file descriptor req->sd for us
if (req->errsd != req->sd) { dnssd_close(req->errsd); req->errsd = req->sd; }
@@ -1079,7 +1082,7 @@ mDNSlocal void connection_termination(request_state *request)
mDNSlocal void handle_cancel_request(request_state *request)
{
request_state **req = &all_requests;
- LogOperation("%3d: Cancel %08X %08X", request->sd, request->hdr.client_context.u32[1], request->hdr.client_context.u32[0]);
+ LogDebug("%3d: Cancel %08X %08X", request->sd, request->hdr.client_context.u32[1], request->hdr.client_context.u32[0]);
while (*req)
{
if ((*req)->primary == request &&
@@ -1691,7 +1694,7 @@ mDNSlocal mStatus register_service_instance(request_state *request, const domain
&request->u.servicereg.name, &request->u.servicereg.type, domain,
request->u.servicereg.host.c[0] ? &request->u.servicereg.host : NULL,
request->u.servicereg.port,
- request->u.servicereg.txtdata, request->u.servicereg.txtlen,
+ mDNSNULL, request->u.servicereg.txtdata, request->u.servicereg.txtlen,
instance->subtypes, request->u.servicereg.num_subtypes,
interfaceID, regservice_callback, instance, request->flags);
@@ -2168,7 +2171,7 @@ mDNSlocal mStatus add_domain_to_browser(request_state *info, const domainname *d
{
domainname tmp;
ConstructServiceName(&tmp, NULL, &info->u.browser.regtype, &b->domain);
- LogInfo("add_domain_to_browser: calling external_start_browsing_for_service()");
+ LogDebug("add_domain_to_browser: calling external_start_browsing_for_service()");
external_start_browsing_for_service(info->u.browser.interface_id, &tmp, kDNSType_PTR, info->flags);
}
}
@@ -3164,7 +3167,7 @@ mDNSlocal mDNSBool RetryQuestionWithSearchDomains(DNSQuestion *question, request
}
else
{
- LogInfo("%3d: RetryQuestionWithSearchDomains: Not appending search domains - SuppressQuery %d, SearchListIndex %d, AppendSearchDomains %d", req->sd, AddRecord, question->SearchListIndex, question->AppendSearchDomains);
+ LogDebug("%3d: RetryQuestionWithSearchDomains: Not appending search domains - SuppressQuery %d, SearchListIndex %d, AppendSearchDomains %d", req->sd, AddRecord, question->SearchListIndex, question->AppendSearchDomains);
}
return mDNSfalse;
}
@@ -3180,10 +3183,11 @@ mDNSlocal void queryrecord_result_reply(mDNS *const m, request_state *req, DNSQu
ConvertDomainNameToCString(answer->name, name);
- LogOperation("%3d: %s(%##s, %s) RESULT %s interface %d: %s", req->sd,
+ LogOperation("%3d: %s(%##s, %s) RESULT %s interface %d: (%s)%s", req->sd,
req->hdr.op == query_request ? "DNSServiceQueryRecord" : "DNSServiceGetAddrInfo",
question->qname.c, DNSTypeName(question->qtype), AddRecord ? "ADD" : "RMV",
- mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID, mDNSfalse), RRDisplayString(m, answer));
+ mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID, mDNSfalse),
+ MortalityDisplayString(answer->mortality), RRDisplayString(m, answer));
len = sizeof(DNSServiceFlags); // calculate reply data length
len += sizeof(mDNSu32); // interface index
@@ -3197,6 +3201,8 @@ mDNSlocal void queryrecord_result_reply(mDNS *const m, request_state *req, DNSQu
if (AddRecord)
flags |= kDNSServiceFlagsAdd;
+ if (answer->mortality == Mortality_Ghost)
+ flags |= kDNSServiceFlagsExpiredAnswer;
if (question->ValidationStatus != 0)
{
error = kDNSServiceErr_NoError;
@@ -3454,7 +3460,7 @@ mDNSlocal void queryrecord_result_callback(mDNS *const m, DNSQuestion *question,
// the "core" needs to temporarily turn off SuppressQuery to answer this query.
if (AddRecord == QC_suppressed)
{
- LogInfo("queryrecord_result_callback: Suppressed question %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
+ LogDebug("queryrecord_result_callback: Suppressed question %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
queryrecord_result_reply(m, req, question, answer, AddRecord, kDNSServiceErr_NoSuchRecord);
return;
}
@@ -3519,7 +3525,7 @@ mDNSlocal void queryrecord_result_callback(mDNS *const m, DNSQuestion *question,
// appended .local, we need to see if we need to send an additional query. This should
// normally happen just once because after we append .local, we ignore all negative
// responses for .local above.
- LogInfo("queryrecord_result_callback: Retrying question %##s (%s) after appending search domains", question->qname.c, DNSTypeName(question->qtype));
+ LogDebug("queryrecord_result_callback: Retrying question %##s (%s) after appending search domains", question->qname.c, DNSTypeName(question->qtype));
if (RetryQuestionWithSearchDomains(question, req, AddRecord))
{
// Note: We need to call SendAdditionalQuery every time after appending a search domain as .local could
@@ -3648,34 +3654,35 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
request->interfaceIndex = interfaceIndex;
mDNSPlatformMemZero(&request->u.queryrecord, sizeof(request->u.queryrecord));
- q->InterfaceID = InterfaceID;
- q->flags = flags;
- q->Target = zeroAddr;
+ q->InterfaceID = InterfaceID;
+ q->flags = flags;
+ q->Target = zeroAddr;
if (!MakeDomainNameFromDNSNameString(&q->qname, name)) return(mStatus_BadParamErr);
#if 0
if (!AuthorizedDomain(request, &q->qname, AutoBrowseDomains)) return (mStatus_NoError);
#endif
- q->qtype = rrtype;
- q->qclass = rrclass;
- q->LongLived = (flags & kDNSServiceFlagsLongLivedQuery ) != 0;
- q->ExpectUnique = mDNSfalse;
- q->ForceMCast = (flags & kDNSServiceFlagsForceMulticast ) != 0;
- q->ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
- q->SuppressUnusable = (flags & kDNSServiceFlagsSuppressUnusable ) != 0;
- q->TimeoutQuestion = (flags & kDNSServiceFlagsTimeout ) != 0;
- q->WakeOnResolve = 0;
+ q->qtype = rrtype;
+ q->qclass = rrclass;
+ q->LongLived = (flags & kDNSServiceFlagsLongLivedQuery ) != 0;
+ q->ExpectUnique = mDNSfalse;
+ q->ForceMCast = (flags & kDNSServiceFlagsForceMulticast ) != 0;
+ q->ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
+ q->SuppressUnusable = (flags & kDNSServiceFlagsSuppressUnusable ) != 0;
+ q->TimeoutQuestion = (flags & kDNSServiceFlagsTimeout ) != 0;
+ q->allowExpired = (EnableAllowExpired && (flags & kDNSServiceFlagsAllowExpiredAnswers) != 0) ? AllowExpired_AllowExpiredAnswers : AllowExpired_None;
+ q->WakeOnResolve = 0;
q->UseBackgroundTrafficClass = (flags & kDNSServiceFlagsBackgroundTrafficClass) != 0;
if ((flags & kDNSServiceFlagsValidate) != 0)
q->ValidationRequired = DNSSEC_VALIDATION_SECURE;
else if ((flags & kDNSServiceFlagsValidateOptional) != 0)
q->ValidationRequired = DNSSEC_VALIDATION_SECURE_OPTIONAL;
q->ValidatingResponse = 0;
- q->ProxyQuestion = 0;
+ q->ProxyQuestion = 0;
q->AnonInfo = mDNSNULL;
- q->QuestionCallback = queryrecord_result_callback;
- q->QuestionContext = request;
- q->SearchListIndex = 0;
- q->StopTime = 0;
+ q->QuestionCallback = queryrecord_result_callback;
+ q->QuestionContext = request;
+ q->SearchListIndex = 0;
+ q->StopTime = 0;
q->DNSSECAuthInfo = mDNSNULL;
q->DAIFreeCallback = mDNSNULL;
@@ -3739,7 +3746,7 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
LogMcastQ(q, request, q_start);
if (callExternalHelpers(q->InterfaceID, &q->qname, q->flags))
{
- LogInfo("handle_queryrecord_request: calling external_start_browsing_for_service()");
+ LogDebug("handle_queryrecord_request: calling external_start_browsing_for_service()");
external_start_browsing_for_service(q->InterfaceID, &q->qname, q->qtype, q->flags);
}
}
@@ -4260,7 +4267,7 @@ mDNSlocal void addrinfo_termination_callback(request_state *request)
if (callExternalHelpers(request->u.addrinfo.interface_id, &request->u.addrinfo.q4.qname, request->flags))
{
- LogInfo("addrinfo_termination_callback: calling external_stop_browsing_for_service() for kDNSServiceType_A record");
+ LogInfo("addrinfo_termination_callback: calling external_stop_browsing_for_service() for A record");
external_stop_browsing_for_service(request->u.addrinfo.interface_id, &request->u.addrinfo.q4.qname, kDNSServiceType_A, request->flags);
}
}
@@ -4295,7 +4302,7 @@ mDNSlocal void addrinfo_termination_callback(request_state *request)
if (callExternalHelpers(request->u.addrinfo.interface_id, &request->u.addrinfo.q6.qname, request->flags))
{
- LogInfo("addrinfo_termination_callback: calling external_stop_browsing_for_service() for kDNSServiceType_AAAA record");
+ LogInfo("addrinfo_termination_callback: calling external_stop_browsing_for_service() for AAAA record");
external_stop_browsing_for_service(request->u.addrinfo.interface_id, &request->u.addrinfo.q6.qname, kDNSServiceType_AAAA, request->flags);
}
}
@@ -4425,19 +4432,20 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
request->u.addrinfo.protocol = (kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6);
}
- request->u.addrinfo.q4.InterfaceID = request->u.addrinfo.q6.InterfaceID = request->u.addrinfo.interface_id;
- request->u.addrinfo.q4.ServiceID = request->u.addrinfo.q6.ServiceID = serviceIndex;
- request->u.addrinfo.q4.flags = request->u.addrinfo.q6.flags = flags;
- request->u.addrinfo.q4.Target = request->u.addrinfo.q6.Target = zeroAddr;
- request->u.addrinfo.q4.qname = request->u.addrinfo.q6.qname = d;
- request->u.addrinfo.q4.qclass = request->u.addrinfo.q6.qclass = kDNSServiceClass_IN;
- request->u.addrinfo.q4.LongLived = request->u.addrinfo.q6.LongLived = (flags & kDNSServiceFlagsLongLivedQuery ) != 0;
- request->u.addrinfo.q4.ExpectUnique = request->u.addrinfo.q6.ExpectUnique = mDNSfalse;
- request->u.addrinfo.q4.ForceMCast = request->u.addrinfo.q6.ForceMCast = (flags & kDNSServiceFlagsForceMulticast ) != 0;
- request->u.addrinfo.q4.ReturnIntermed = request->u.addrinfo.q6.ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
- request->u.addrinfo.q4.SuppressUnusable = request->u.addrinfo.q6.SuppressUnusable = (flags & kDNSServiceFlagsSuppressUnusable ) != 0;
- request->u.addrinfo.q4.TimeoutQuestion = request->u.addrinfo.q6.TimeoutQuestion = (flags & kDNSServiceFlagsTimeout ) != 0;
- request->u.addrinfo.q4.WakeOnResolve = request->u.addrinfo.q6.WakeOnResolve = 0;
+ request->u.addrinfo.q4.InterfaceID = request->u.addrinfo.q6.InterfaceID = request->u.addrinfo.interface_id;
+ request->u.addrinfo.q4.ServiceID = request->u.addrinfo.q6.ServiceID = serviceIndex;
+ request->u.addrinfo.q4.flags = request->u.addrinfo.q6.flags = flags;
+ request->u.addrinfo.q4.Target = request->u.addrinfo.q6.Target = zeroAddr;
+ request->u.addrinfo.q4.qname = request->u.addrinfo.q6.qname = d;
+ request->u.addrinfo.q4.qclass = request->u.addrinfo.q6.qclass = kDNSServiceClass_IN;
+ request->u.addrinfo.q4.LongLived = request->u.addrinfo.q6.LongLived = (flags & kDNSServiceFlagsLongLivedQuery ) != 0;
+ request->u.addrinfo.q4.ExpectUnique = request->u.addrinfo.q6.ExpectUnique = mDNSfalse;
+ request->u.addrinfo.q4.ForceMCast = request->u.addrinfo.q6.ForceMCast = (flags & kDNSServiceFlagsForceMulticast ) != 0;
+ request->u.addrinfo.q4.ReturnIntermed = request->u.addrinfo.q6.ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
+ request->u.addrinfo.q4.SuppressUnusable = request->u.addrinfo.q6.SuppressUnusable = (flags & kDNSServiceFlagsSuppressUnusable ) != 0;
+ request->u.addrinfo.q4.TimeoutQuestion = request->u.addrinfo.q6.TimeoutQuestion = (flags & kDNSServiceFlagsTimeout ) != 0;
+ request->u.addrinfo.q4.allowExpired = request->u.addrinfo.q6.allowExpired = (EnableAllowExpired && (flags & kDNSServiceFlagsAllowExpiredAnswers) != 0) ? AllowExpired_AllowExpiredAnswers : AllowExpired_None;
+ request->u.addrinfo.q4.WakeOnResolve = request->u.addrinfo.q6.WakeOnResolve = 0;
request->u.addrinfo.q4.UseBackgroundTrafficClass = request->u.addrinfo.q6.UseBackgroundTrafficClass = (flags & kDNSServiceFlagsBackgroundTrafficClass) != 0;
if ((flags & kDNSServiceFlagsValidate) != 0)
request->u.addrinfo.q4.ValidationRequired = request->u.addrinfo.q6.ValidationRequired = DNSSEC_VALIDATION_SECURE;
@@ -4499,7 +4507,7 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
LogMcastQ(&request->u.addrinfo.q6, request, q_start);
if (callExternalHelpers(InterfaceID, &d, flags))
{
- LogInfo("handle_addrinfo_request: calling external_start_browsing_for_service() for kDNSServiceType_AAAA record");
+ LogDebug("handle_addrinfo_request: calling external_start_browsing_for_service() for AAAA record");
external_start_browsing_for_service(InterfaceID, &d, kDNSServiceType_AAAA, flags);
}
}
@@ -4541,7 +4549,7 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
if (callExternalHelpers(InterfaceID, &d, flags))
{
- LogInfo("addrinfo_termination_callback: calling external_stop_browsing_for_service() for kDNSServiceType_AAAA record");
+ LogInfo("addrinfo_termination_callback: calling external_stop_browsing_for_service() for AAAA record");
external_stop_browsing_for_service(InterfaceID, &d, kDNSServiceType_AAAA, flags);
}
}
@@ -4555,7 +4563,7 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
LogMcastQ(&request->u.addrinfo.q4, request, q_start);
if (callExternalHelpers(InterfaceID, &d, flags))
{
- LogInfo("handle_addrinfo_request: calling external_start_browsing_for_service() for kDNSServiceType_A record");
+ LogDebug("handle_addrinfo_request: calling external_start_browsing_for_service() for A record");
external_start_browsing_for_service(InterfaceID, &d, kDNSServiceType_A, flags);
}
}
@@ -4755,7 +4763,7 @@ mDNSlocal void read_msg(request_state *req)
#if !defined(USE_TCP_LOOPBACK)
got_errfd:
#endif
- LogOperation("%3d: Result code socket %d created %08X %08X", req->sd, req->errsd, req->hdr.client_context.u32[1], req->hdr.client_context.u32[0]);
+ LogDebug("%3d: Result code socket %d created %08X %08X", req->sd, req->errsd, req->hdr.client_context.u32[1], req->hdr.client_context.u32[0]);
#if defined(_WIN32)
if (ioctlsocket(req->errsd, FIONBIO, &opt) != 0)
#else
@@ -4954,8 +4962,8 @@ mDNSlocal void request_callback(int fd, short filter, void *info)
send_all(req->errsd, (const char *)&err_netorder, sizeof(err_netorder));
if (req->errsd != req->sd)
{
- LogOperation("%3d: Result code socket %d closed %08X %08X (%d)",
- req->sd, req->errsd, req->hdr.client_context.u32[1], req->hdr.client_context.u32[0], err);
+ LogDebug("%3d: Result code socket %d closed %08X %08X (%d)",
+ req->sd, req->errsd, req->hdr.client_context.u32[1], req->hdr.client_context.u32[0], err);
dnssd_close(req->errsd);
req->errsd = req->sd;
// Also need to reset the parent's errsd, if this is a subordinate operation
@@ -5026,7 +5034,7 @@ mDNSlocal void connect_callback(int fd, short filter, void *info)
debugf("LOCAL_PEERCRED %d %u %u %d", xucredlen, x.cr_version, x.cr_uid, x.cr_ngroups);
#endif // APPLE_OSX_mDNSResponder
- LogOperation("%3d: connect_callback: Adding FD for uid %u", request->sd, request->uid);
+ LogDebug("%3d: connect_callback: Adding FD for uid %u", request->sd, request->uid);
udsSupportAddFDToEventLoop(sd, request_callback, request, &request->platform_data);
}
}
@@ -5087,7 +5095,7 @@ mDNSexport int udsserver_init(dnssd_sock_t skts[], mDNSu32 count)
FILE *fp = fopen(PID_FILE, "w");
if (fp != NULL)
{
- fprintf(fp, "%d\n", getpid());
+ fprintf(fp, "%d\n", (int)getpid());
fclose(fp);
}
}
@@ -6256,10 +6264,10 @@ struct CompileTimeAssertionChecks_uds_daemon
// Check our structures are reasonable sizes. Including overly-large buffers, or embedding
// other overly-large structures instead of having a pointer to them, can inadvertently
// cause structure sizes (and therefore memory usage) to balloon unreasonably.
- char sizecheck_request_state [(sizeof(request_state) <= 2954) ? 1 : -1];
+ char sizecheck_request_state [(sizeof(request_state) <= 3696) ? 1 : -1];
char sizecheck_registered_record_entry[(sizeof(registered_record_entry) <= 60) ? 1 : -1];
char sizecheck_service_instance [(sizeof(service_instance) <= 6552) ? 1 : -1];
- char sizecheck_browser_t [(sizeof(browser_t) <= 1202) ? 1 : -1];
+ char sizecheck_browser_t [(sizeof(browser_t) <= 1432) ? 1 : -1];
char sizecheck_reply_hdr [(sizeof(reply_hdr) <= 12) ? 1 : -1];
char sizecheck_reply_state [(sizeof(reply_state) <= 64) ? 1 : -1];
};