summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2016-06-21 15:45:49 +0300
committerRobert Mustacchi <rm@joyent.com>2016-07-22 07:39:00 -0700
commitcda73f64f20b8a0afc4909f5ea1f055ec7913856 (patch)
tree6f93e00913bd2c9f2aab6396979ba091da82dde6
parent6da83bb0b886fae280a129718d645576517b62c6 (diff)
downloadillumos-joyent-cda73f64f20b8a0afc4909f5ea1f055ec7913856.tar.gz
7139 Sync mDNS with mDNSResponder-625.41.2
Reviewed by: Dan McDonald <danmcd@omniti.com> Reviewed by: Andy Stormont <astormont@racktopsystems.com> Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r--usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.c6
-rw-r--r--usr/src/cmd/cmd-inet/usr.bin/dns-sd/Makefile5
-rw-r--r--usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c52
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.c2
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.h3
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.c127
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.h14
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSDigest.c3
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.c9
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.c19
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/PosixDaemon.c2
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.c39
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.h2
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/dnssec.h3
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNS.c956
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.c9
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.h10
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSEmbeddedAPI.h93
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.c101
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.c71
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/nsec.h3
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.c80
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.c223
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.h11
-rw-r--r--usr/src/lib/libdns_sd/README3
-rw-r--r--usr/src/lib/libdns_sd/common/dns_sd.h47
-rw-r--r--usr/src/lib/libdns_sd/common/dnssd_clientlib.c4
-rw-r--r--usr/src/lib/libdns_sd/common/dnssd_clientstub.c114
-rw-r--r--usr/src/lib/libdns_sd/common/dnssd_ipc.c4
-rw-r--r--usr/src/lib/libdns_sd/common/dnssd_ipc.h6
30 files changed, 1067 insertions, 954 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.c b/usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.c
index 68f354ccac..cb59e7b9b8 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.c
+++ b/usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.c
@@ -1,8 +1,8 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2011 Apple Inc. All rights reserved.
*
- * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
* ("Apple") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this Apple software
* constitutes acceptance of these terms. If you do not agree with these terms,
@@ -16,7 +16,7 @@
* the Apple Software in its entirety and without modifications, you must retain
* this notice and the following text and disclaimers in all such redistributions of
* the Apple Software. Neither the name, trademarks, service marks or logos of
- * Apple Computer, Inc. may be used to endorse or promote products derived from the
+ * Apple Inc. may be used to endorse or promote products derived from the
* Apple Software without specific prior written permission from Apple. Except as
* expressly stated in this notice, no other rights or licenses, express or implied,
* are granted by Apple herein, including but not limited to any patent rights that
diff --git a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/Makefile b/usr/src/cmd/cmd-inet/usr.bin/dns-sd/Makefile
index 01c94af04d..293a4f5976 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/Makefile
+++ b/usr/src/cmd/cmd-inet/usr.bin/dns-sd/Makefile
@@ -37,12 +37,11 @@ $(PROG): $(OBJS)
$(LINK.c) $(OBJS) -o $@ $(LDLIBS)
$(POST_PROCESS)
-install: all $(ROOTPROG)
+install: all $(ROOTPROG)
clean:
$(RM) $(OBJS)
-lint: lint_SRCS
+lint: lint_SRCS
include ../../../Makefile.targ
-
diff --git a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c b/usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c
index 3be1426794..9199887c5e 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c
+++ b/usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c
@@ -1,8 +1,8 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
- * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
* ("Apple") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this Apple software
* constitutes acceptance of these terms. If you do not agree with these terms,
@@ -16,7 +16,7 @@
* the Apple Software in its entirety and without modifications, you must retain
* this notice and the following text and disclaimers in all such redistributions of
* the Apple Software. Neither the name, trademarks, service marks or logos of
- * Apple Computer, Inc. may be used to endorse or promote products derived from the
+ * Apple Inc. may be used to endorse or promote products derived from the
* Apple Software without specific prior written permission from Apple. Except as
* expressly stated in this notice, no other rights or licenses, express or implied,
* are granted by Apple herein, including but not limited to any patent rights that
@@ -57,14 +57,6 @@
// aren't in the system's /usr/lib/libSystem.dylib.
//#define TEST_NEW_CLIENTSTUB 1
-// When building mDNSResponder for Mac OS X 10.4 and earlier, /usr/lib/libSystem.dylib is built using its own private
-// copy of dnssd_clientstub.c, which is old and doesn't have all the entry points defined in the latest version, so
-// when we're building dns-sd.c on Mac OS X 10.4 or earlier, we automatically set TEST_NEW_CLIENTSTUB so that we'll
-// embed a copy of the latest dnssd_clientstub.c instead of trying to link to the incomplete version in libSystem.dylib
-#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ <= 1040
-#define TEST_NEW_CLIENTSTUB 1
-#endif
-
#include <ctype.h>
#include <stdio.h> // For stdout, stderr
#include <stdlib.h> // For exit()
@@ -185,14 +177,6 @@ static const char kFilePathSep = '/';
#include <dispatch/private.h>
#endif
-// The "+0" is to cope with the case where _DNS_SD_H is defined but empty (e.g. on Mac OS X 10.4 and earlier)
-#if _DNS_SD_H+0 >= 116
-#define HAS_NAT_PMP_API 1
-#define HAS_ADDRINFO_API 1
-#else
-#define kDNSServiceFlagsReturnIntermediates 0
-#endif
-
//*************************************************************************************************************
// Globals
@@ -421,7 +405,6 @@ done:
#endif //_DNS_SD_LIBDISPATCH
}
-#if HAS_NAT_PMP_API | HAS_ADDRINFO_API
static DNSServiceProtocol GetProtocol(const char *s)
{
if (!strcasecmp(s, "v4" )) return(kDNSServiceProtocol_IPv4);
@@ -434,7 +417,6 @@ static DNSServiceProtocol GetProtocol(const char *s)
else if (!strcasecmp(s, "tcpudp" )) return(kDNSServiceProtocol_UDP | kDNSServiceProtocol_TCP);
else return(atoi(s));
}
-#endif
//*************************************************************************************************************
@@ -494,18 +476,14 @@ static void print_usage(const char *arg0, int print_all)
fprintf(stderr, "%s -q <name> <rrtype> <rrclass> (Generic query for any record type)\n", arg0);
fprintf(stderr, "%s -D <name> <rrtype> <rrclass>(Validate query for any record type with DNSSEC)\n", arg0);
fprintf(stderr, "%s -Z <Type> <Domain> (Output results in Zone File format)\n", arg0);
-#if HAS_ADDRINFO_API
fprintf(stderr, "%s -G v4/v6/v4v6 <name> (Get address information for hostname)\n", arg0);
fprintf(stderr, "%s -g v4/v6/v4v6 <name> (Validate address info for hostname with DNSSEC)\n", arg0);
-#endif
fprintf(stderr, "%s -V (Get version of currently running daemon / system service)\n", arg0);
if (print_all) //Print all available options for dns-sd tool
{
fprintf(stderr, "%s -C <FQDN> <rrtype> <rrclass> (Query; reconfirming each result)\n", arg0);
-#if HAS_NAT_PMP_API
fprintf(stderr, "%s -X udp/tcp/udptcp <IntPort> <ExtPort> <TTL> (NAT Port Mapping)\n", arg0);
-#endif
fprintf(stderr, "%s -A (Test Adding/Updating/Deleting a record)\n", arg0);
fprintf(stderr, "%s -U (Test updating a TXT record)\n", arg0);
fprintf(stderr, "%s -N (Test adding a large NULL record)\n", arg0);
@@ -1041,15 +1019,15 @@ static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags,
case kDNSServiceType_CNAME:
case kDNSServiceType_PTR:
case kDNSServiceType_DNAME:
- p += snprintd(p, sizeof(rdb), &rd);
+ snprintd(p, sizeof(rdb), &rd);
break;
case kDNSServiceType_SOA:
p += snprintd(p, rdb + sizeof(rdb) - p, &rd); // mname
p += snprintf(p, rdb + sizeof(rdb) - p, " ");
p += snprintd(p, rdb + sizeof(rdb) - p, &rd); // rname
- p += snprintf(p, rdb + sizeof(rdb) - p, " Ser %d Ref %d Ret %d Exp %d Min %d",
- ntohl(((uint32_t*)rd)[0]), ntohl(((uint32_t*)rd)[1]), ntohl(((uint32_t*)rd)[2]), ntohl(((uint32_t*)rd)[3]), ntohl(((uint32_t*)rd)[4]));
+ snprintf(p, rdb + sizeof(rdb) - p, " Ser %d Ref %d Ret %d Exp %d Min %d",
+ ntohl(((uint32_t*)rd)[0]), ntohl(((uint32_t*)rd)[1]), ntohl(((uint32_t*)rd)[2]), ntohl(((uint32_t*)rd)[3]), ntohl(((uint32_t*)rd)[4]));
break;
case kDNSServiceType_AAAA:
@@ -1060,9 +1038,9 @@ static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags,
case kDNSServiceType_SRV:
p += snprintf(p, rdb + sizeof(rdb) - p, "%d %d %d ", // priority, weight, port
- ntohs(*(unsigned short*)rd), ntohs(*(unsigned short*)(rd+2)), ntohs(*(unsigned short*)(rd+4)));
+ ntohs(*(unsigned short*)rd), ntohs(*(unsigned short*)(rd+2)), ntohs(*(unsigned short*)(rd+4)));
rd += 6;
- p += snprintd(p, rdb + sizeof(rdb) - p, &rd); // target host
+ snprintd(p, rdb + sizeof(rdb) - p, &rd); // target host
break;
case kDNSServiceType_DS:
@@ -1124,7 +1102,6 @@ static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags,
fflush(stdout);
}
-#if HAS_NAT_PMP_API
static void DNSSD_API port_mapping_create_reply(DNSServiceRef sdref, DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode, uint32_t publicAddress, uint32_t protocol, uint16_t privatePort, uint16_t publicPort, uint32_t ttl, void *context)
{
(void)sdref; // Unused
@@ -1146,9 +1123,7 @@ static void DNSSD_API port_mapping_create_reply(DNSServiceRef sdref, DNSServiceF
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
}
-#endif
-#if HAS_ADDRINFO_API
static void DNSSD_API addrinfo_reply(DNSServiceRef sdref, const DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context)
{
char *op = (flags & kDNSServiceFlagsAdd) ? "Add" : "Rmv";
@@ -1218,7 +1193,6 @@ static void DNSSD_API addrinfo_reply(DNSServiceRef sdref, const DNSServiceFlags
if (!(flags & kDNSServiceFlagsMoreComing))
fflush(stdout);
}
-#endif
//*************************************************************************************************************
// The main test function
@@ -1362,6 +1336,7 @@ static DNSServiceErrorType RegisterProxyAddressRecord(DNSServiceRef sdref, const
// Any DNSService* call will initialize WinSock for us, so we make sure
// DNSServiceCreateConnection() is called before getip() is.
struct sockaddr_storage hostaddr;
+ memset(&hostaddr, 0, sizeof(hostaddr));
getip(ip, &hostaddr);
flags |= kDNSServiceFlagsUnique;
if (hostaddr.ss_family == AF_INET)
@@ -1553,12 +1528,8 @@ int main(int argc, char **argv)
if (argc < 2) goto Fail; // Minimum command line is the command name and one argument
operation = getfirstoption(argc, argv, "EFBZLlRPQqCAUNTMISVHhD"
- #if HAS_NAT_PMP_API
"X"
- #endif
- #if HAS_ADDRINFO_API
"Gg"
- #endif
, &opi);
if (operation == -1) goto Fail;
@@ -1592,6 +1563,7 @@ int main(int argc, char **argv)
if (dom[0] == '.' && dom[1] == 0) dom[0] = 0; // We allow '.' on the command line as a synonym for empty string
printf("Browsing for %s%s%s\n", typ, dom[0] ? "." : "", dom);
err = DNSServiceCreateConnection(&client);
+ if (err) { fprintf(stderr, "DNSServiceCreateConnection returned %d\n", err); return(err); }
sc1 = client;
err = DNSServiceBrowse(&sc1, kDNSServiceFlagsShareConnection, opinterface, typ, dom, zonedata_browse, NULL);
break;
@@ -1694,7 +1666,6 @@ int main(int argc, char **argv)
break;
}
-#if HAS_NAT_PMP_API
case 'X': {
if (argc == opi) // If no arguments, just fetch IP address
err = DNSServiceNATPortMappingCreate(&client, 0, 0, 0, 0, 0, 0, port_mapping_create_reply, NULL);
@@ -1711,9 +1682,7 @@ int main(int argc, char **argv)
else goto Fail;
break;
}
-#endif
-#if HAS_ADDRINFO_API
case 'g':
case 'G': {
flags |= kDNSServiceFlagsReturnIntermediates;
@@ -1731,7 +1700,6 @@ int main(int argc, char **argv)
err = DNSServiceGetAddrInfo(&client, flags, opinterface, GetProtocol(argv[opi+0]), argv[opi+1], addrinfo_reply, NULL);
break;
}
-#endif
case 'S': {
Opaque16 registerPort = { { 0x23, 0x45 } }; // 9029 decimal
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.c
index 38533fc886..0008405ddd 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.h b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.h
index 6cb3dc9d24..c21507e4b1 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.h
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#ifndef __CRYPTO_ALG_H
#define __CRYPTO_ALG_H
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.c
index a0dbfcd728..607293e838 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -513,7 +513,7 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
expTimeBuf, inceptTimeBuf, swap16(rrsig->keyTag), ((domainname *)(&rrsig->signerName))->c);
len = DomainNameLength((domainname *)&rrsig->signerName);
- length += baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + len + RRSIG_FIXED_SIZE),
+ baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + len + RRSIG_FIXED_SIZE),
rr->rdlength - (len + RRSIG_FIXED_SIZE), ENC_BASE64);
}
break;
@@ -521,7 +521,7 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
rdataDNSKey *rrkey = (rdataDNSKey *)rd->data;
length += mDNS_snprintf(buffer+length, RemSpc, "\t%d %d %s %u ", swap16(rrkey->flags), rrkey->proto,
DNSSECAlgName(rrkey->alg), (unsigned int)keytag((mDNSu8 *)rrkey, rr->rdlength));
- length += baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + DNSKEY_FIXED_SIZE),
+ baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + DNSKEY_FIXED_SIZE),
rr->rdlength - DNSKEY_FIXED_SIZE, ENC_BASE64);
}
break;
@@ -1481,6 +1481,7 @@ mDNSexport void mDNS_SetupQuestion(DNSQuestion *const q, const mDNSInterfaceID I
q->qnameOrig = mDNSNULL;
q->AnonInfo = mDNSNULL;
q->pid = mDNSPlatformGetPID();
+ q->euid = 0;
q->DisallowPID = mDNSfalse;
q->ServiceID = -1;
q->QuestionCallback = callback;
@@ -2357,13 +2358,9 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
case kDNSType_NSEC: {
// For NSEC records, rdlength represents the exact number of bytes
// of in memory storage.
- int len = rr->rdlength;
mDNSu8 *nsec = (mDNSu8 *)rdb->data;
domainname *name = (domainname *)nsec;
- int dlen;
-
- dlen = DomainNameLength(name);
- len -= dlen;
+ const int dlen = DomainNameLength(name);
nsec += dlen;
// This function is called when we are sending a NSEC record as part of mDNS,
// or to copy the data to any other buffer needed which could be a mDNS or uDNS
@@ -2376,7 +2373,6 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
int i, j, wlen;
wlen = *(nsec + 1);
nsec += 2; // Skip the window number and len
- len -= 2;
// For our simplified use of NSEC synthetic records:
//
@@ -2406,6 +2402,7 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
else
{
int win, wlen;
+ int len = rr->rdlength - dlen;
// Sanity check whether the bitmap is good
while (len)
@@ -2607,7 +2604,7 @@ mDNSexport mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domain
}
// for dynamic updates
-mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease)
+mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease)
{
AuthRecord rr;
mDNS_SetupResourceRecord(&rr, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
@@ -2616,13 +2613,13 @@ mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease)
rr.resrec.rdestimate = sizeof(rdataOPT);
rr.resrec.rdata->u.opt[0].opt = kDNSOpt_Lease;
rr.resrec.rdata->u.opt[0].u.updatelease = lease;
- end = PutResourceRecordTTLJumbo(msg, end, &msg->h.numAdditionals, &rr.resrec, 0);
- if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTL"); return mDNSNULL; }
- return end;
+ ptr = PutResourceRecordTTLJumbo(msg, ptr, &msg->h.numAdditionals, &rr.resrec, 0);
+ if (!ptr) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTL"); return mDNSNULL; }
+ return ptr;
}
// for dynamic updates
-mDNSexport mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease, mDNSu8 *limit)
+mDNSexport mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease, mDNSu8 *limit)
{
AuthRecord rr;
mDNS_SetupResourceRecord(&rr, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
@@ -2631,9 +2628,9 @@ mDNSexport mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *end, mDNSu32
rr.resrec.rdestimate = sizeof(rdataOPT);
rr.resrec.rdata->u.opt[0].opt = kDNSOpt_Lease;
rr.resrec.rdata->u.opt[0].u.updatelease = lease;
- end = PutResourceRecordTTLWithLimit(msg, end, &msg->h.numAdditionals, &rr.resrec, 0, limit);
- if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
- return end;
+ ptr = PutResourceRecordTTLWithLimit(msg, ptr, &msg->h.numAdditionals, &rr.resrec, 0, limit);
+ if (!ptr) { LogMsg("ERROR: putUpdateLeaseWithLimit - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
+ return ptr;
}
mDNSexport mDNSu8 *putDNSSECOption(DNSMessage *msg, mDNSu8 *end, mDNSu8 *limit)
@@ -2650,7 +2647,7 @@ mDNSexport mDNSu8 *putDNSSECOption(DNSMessage *msg, mDNSu8 *end, mDNSu8 *limit)
// set the DO bit
ttl |= 0x8000;
end = PutResourceRecordTTLWithLimit(msg, end, &msg->h.numAdditionals, &rr.resrec, ttl, limit);
- if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
+ if (!end) { LogMsg("ERROR: putDNSSECOption - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
return end;
}
@@ -3441,12 +3438,7 @@ mDNSexport const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage
mDNSu16 pktrdlength;
if (largecr == &m->rec && m->rec.r.resrec.RecordType)
- {
- LogMsg("GetLargeResourceRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
-#if ForceAlerts
- *(long*)0 = 0;
-#endif
- }
+ LogFatalError("GetLargeResourceRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
rr->next = mDNSNULL;
rr->resrec.name = &largecr->namestorage;
@@ -3713,7 +3705,7 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
}
ptr = DumpRecords(m, msg, ptr, end, msg->h.numAnswers, IsUpdate ? "Prerequisites" : "Answers");
ptr = DumpRecords(m, msg, ptr, end, msg->h.numAuthorities, IsUpdate ? "Updates" : "Authorities");
- ptr = DumpRecords(m, msg, ptr, end, msg->h.numAdditionals, "Additionals");
+ DumpRecords(m, msg, ptr, end, msg->h.numAdditionals, "Additionals");
LogMsg("--------------");
}
@@ -3725,11 +3717,8 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
// Stub definition of TCPSocket_struct so we can access flags field. (Rest of TCPSocket_struct is platform-dependent.)
struct TCPSocket_struct { TCPSocketFlags flags; /* ... */ };
-
-struct UDPSocket_struct
-{
- mDNSIPPort port; // MUST BE FIRST FIELD -- mDNSCoreReceive expects every UDPSocket_struct to begin with mDNSIPPort port
-};
+// Stub definition of UDPSocket_struct so we can access port field. (Rest of UDPSocket_struct is platform-dependent.)
+struct UDPSocket_struct { mDNSIPPort port; /* ... */ };
// Note: When we sign a DNS message using DNSDigest_SignMessage(), the current real-time clock value is used, which
// is why we generally defer signing until we send the message, to ensure the signature is as fresh as possible.
@@ -3821,10 +3810,10 @@ 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)) {
mDNSIPPort port = MulticastDNSPort;
- DumpPacket(m, status, mDNStrue, sock &&
- (sock->flags & kTCPSocketFlags_UseTLS) ?
- "TLS" : sock ? "TCP" : "UDP", mDNSNULL,
- src ? src->port : port, dst, dstport, msg, end);
+ DumpPacket(m, status, mDNStrue,
+ sock && (sock->flags & kTCPSocketFlags_UseTLS) ?
+ "TLS" : sock ? "TCP" : "UDP", mDNSNULL,
+ src ? src->port : port, dst, dstport, msg, end);
}
// put the number of additionals back the way it was
@@ -3849,12 +3838,7 @@ mDNSexport void mDNS_Lock_(mDNS *const m, const char * const functionname)
// If that client callback does mDNS API calls, mDNS_reentrancy and mDNS_busy will both be one
// If mDNS_busy != mDNS_reentrancy that's a bad sign
if (m->mDNS_busy != m->mDNS_reentrancy)
- {
- LogMsg("%s: mDNS_Lock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
-#if ForceAlerts
- *(long*)0 = 0;
-#endif
- }
+ LogFatalError("%s: mDNS_Lock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
// If this is an initial entry into the mDNSCore code, set m->timenow
// else, if this is a re-entrant entry into the mDNSCore code, m->timenow should already be set
@@ -3935,82 +3919,89 @@ mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m)
return(e);
}
+#define LogTSE TSE++,LogMsg
+
mDNSexport void ShowTaskSchedulingError(mDNS *const m)
{
+ int TSE = 0;
AuthRecord *rr;
mDNS_Lock(m);
- LogMsg("Task Scheduling Error: Continuously busy for more than a second");
+ LogMsg("Task Scheduling Error: *** Continuously busy for more than a second");
// Note: To accurately diagnose *why* we're busy, the debugging code here needs to mirror the logic in GetNextScheduledEvent above
if (m->NewQuestions && (!m->NewQuestions->DelayAnswering || m->timenow - m->NewQuestions->DelayAnswering >= 0))
- LogMsg("Task Scheduling Error: NewQuestion %##s (%s)",
+ LogTSE("Task Scheduling Error: NewQuestion %##s (%s)",
m->NewQuestions->qname.c, DNSTypeName(m->NewQuestions->qtype));
if (m->NewLocalOnlyQuestions)
- LogMsg("Task Scheduling Error: NewLocalOnlyQuestions %##s (%s)",
+ LogTSE("Task Scheduling Error: NewLocalOnlyQuestions %##s (%s)",
m->NewLocalOnlyQuestions->qname.c, DNSTypeName(m->NewLocalOnlyQuestions->qtype));
if (m->NewLocalRecords)
{
rr = AnyLocalRecordReady(m);
- if (rr) LogMsg("Task Scheduling Error: NewLocalRecords %s", ARDisplayString(m, rr));
+ if (rr) LogTSE("Task Scheduling Error: NewLocalRecords %s", ARDisplayString(m, rr));
}
- if (m->NewLocalOnlyRecords) LogMsg("Task Scheduling Error: NewLocalOnlyRecords");
+ if (m->NewLocalOnlyRecords) LogTSE("Task Scheduling Error: NewLocalOnlyRecords");
- if (m->SPSProxyListChanged) LogMsg("Task Scheduling Error: SPSProxyListChanged");
- if (m->LocalRemoveEvents) LogMsg("Task Scheduling Error: LocalRemoveEvents");
+ if (m->SPSProxyListChanged) LogTSE("Task Scheduling Error: SPSProxyListChanged");
- if (m->timenow - m->NextScheduledEvent >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledEvent %d", m->timenow - m->NextScheduledEvent);
+ if (m->LocalRemoveEvents) LogTSE("Task Scheduling Error: LocalRemoveEvents");
#ifndef UNICAST_DISABLED
if (m->timenow - m->NextuDNSEvent >= 0)
- LogMsg("Task Scheduling Error: m->NextuDNSEvent %d", m->timenow - m->NextuDNSEvent);
+ LogTSE("Task Scheduling Error: m->NextuDNSEvent %d", m->timenow - m->NextuDNSEvent);
if (m->timenow - m->NextScheduledNATOp >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledNATOp %d", m->timenow - m->NextScheduledNATOp);
+ LogTSE("Task Scheduling Error: m->NextScheduledNATOp %d", m->timenow - m->NextScheduledNATOp);
if (m->NextSRVUpdate && m->timenow - m->NextSRVUpdate >= 0)
- LogMsg("Task Scheduling Error: m->NextSRVUpdate %d", m->timenow - m->NextSRVUpdate);
+ LogTSE("Task Scheduling Error: m->NextSRVUpdate %d", m->timenow - m->NextSRVUpdate);
#endif
if (m->timenow - m->NextCacheCheck >= 0)
- LogMsg("Task Scheduling Error: m->NextCacheCheck %d", m->timenow - m->NextCacheCheck);
+ LogTSE("Task Scheduling Error: m->NextCacheCheck %d", m->timenow - m->NextCacheCheck);
if (m->timenow - m->NextScheduledSPS >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledSPS %d", m->timenow - m->NextScheduledSPS);
+ LogTSE("Task Scheduling Error: m->NextScheduledSPS %d", m->timenow - m->NextScheduledSPS);
if (m->timenow - m->NextScheduledKA >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledKA %d", m->timenow - m->NextScheduledKA);
+ LogTSE("Task Scheduling Error: m->NextScheduledKA %d", m->timenow - m->NextScheduledKA);
if (!m->DelaySleep && m->SleepLimit && m->timenow - m->NextScheduledSPRetry >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledSPRetry %d", m->timenow - m->NextScheduledSPRetry);
+ LogTSE("Task Scheduling Error: m->NextScheduledSPRetry %d", m->timenow - m->NextScheduledSPRetry);
if (m->DelaySleep && m->timenow - m->DelaySleep >= 0)
- LogMsg("Task Scheduling Error: m->DelaySleep %d", m->timenow - m->DelaySleep);
+ LogTSE("Task Scheduling Error: m->DelaySleep %d", m->timenow - m->DelaySleep);
if (m->SuppressSending && m->timenow - m->SuppressSending >= 0)
- LogMsg("Task Scheduling Error: m->SuppressSending %d", m->timenow - m->SuppressSending);
+ LogTSE("Task Scheduling Error: m->SuppressSending %d", m->timenow - m->SuppressSending);
if (m->timenow - m->NextScheduledQuery >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledQuery %d", m->timenow - m->NextScheduledQuery);
+ LogTSE("Task Scheduling Error: m->NextScheduledQuery %d", m->timenow - m->NextScheduledQuery);
if (m->timenow - m->NextScheduledProbe >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledProbe %d", m->timenow - m->NextScheduledProbe);
+ LogTSE("Task Scheduling Error: m->NextScheduledProbe %d", m->timenow - m->NextScheduledProbe);
if (m->timenow - m->NextScheduledResponse >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledResponse %d", m->timenow - m->NextScheduledResponse);
+ LogTSE("Task Scheduling Error: m->NextScheduledResponse %d", m->timenow - m->NextScheduledResponse);
+ if (m->timenow - m->NextScheduledStopTime >= 0)
+ LogTSE("Task Scheduling Error: m->NextScheduledStopTime %d", m->timenow - m->NextScheduledStopTime);
+
+ if (m->timenow - m->NextScheduledEvent >= 0)
+ LogTSE("Task Scheduling Error: m->NextScheduledEvent %d", m->timenow - m->NextScheduledEvent);
+
+ if (m->NetworkChanged && m->timenow - m->NetworkChanged >= 0)
+ LogTSE("Task Scheduling Error: NetworkChanged %d", m->timenow - m->NetworkChanged);
+
+ if (!TSE) LogMsg("Task Scheduling Error: *** No likely causes identified");
+ else LogMsg("Task Scheduling Error: *** %d potential cause%s identified (significant only if the same cause consistently appears)", TSE, TSE > 1 ? "s" : "");
mDNS_Unlock(m);
}
-mDNSexport void mDNS_Unlock_(mDNS *const m, const char * const functionname)
+mDNSexport void mDNS_Unlock_(mDNS *const m, const char *const functionname)
{
// Decrement mDNS_busy
m->mDNS_busy--;
// Check for locking failures
if (m->mDNS_busy != m->mDNS_reentrancy)
- {
- LogMsg("%s: mDNS_Unlock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
-#if ForceAlerts
- *(long*)0 = 0;
-#endif
- }
+ LogFatalError("%s: mDNS_Unlock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
// If this is a final exit from the mDNSCore code, set m->NextScheduledEvent and clear m->timenow
if (m->mDNS_busy == 0)
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.h b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.h
index b92f5a9ab4..e51b06dd7a 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.h
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.h
@@ -220,7 +220,7 @@ extern mDNSu8 *putDeletionRecord(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *r
extern mDNSu8 *putDeletionRecordWithLimit(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *rr, mDNSu8 *limit);
extern mDNSu8 *putDeleteRRSetWithLimit(DNSMessage *msg, mDNSu8 *ptr, const domainname *name, mDNSu16 rrtype, mDNSu8 *limit);
extern mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domainname *name);
-extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease);
+extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease);
extern mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease, mDNSu8 *limit);
extern mDNSu8 *putHINFO(const mDNS *const m, DNSMessage *const msg, mDNSu8 *ptr, DomainAuthInfo *authInfo, mDNSu8 *limit);
@@ -297,16 +297,16 @@ extern void mDNS_Unlock_(mDNS *const m, const char * const functionname);
#define mDNS_Unlock(X) mDNS_Unlock_((X), __func__)
-#define mDNS_CheckLock(X) { if ((X)->mDNS_busy != (X)->mDNS_reentrancy+1) \
- LogMsg("%s: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", __func__, (X)->mDNS_busy, (X)->mDNS_reentrancy); }
+#define mDNS_CheckLock(X) \
+ if ((X)->mDNS_busy != (X)->mDNS_reentrancy+1) LogMsg("%s: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", __func__, (X)->mDNS_busy, (X)->mDNS_reentrancy)
#define mDNS_DropLockBeforeCallback() do { m->mDNS_reentrancy++; \
- if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Locking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
-} while (0)
+ if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Locking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
+ } while (0)
#define mDNS_ReclaimLockAfterCallback() do { \
- if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Unlocking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
- m->mDNS_reentrancy--; } while (0)
+ if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Unlocking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
+ m->mDNS_reentrancy--; } while (0)
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSDigest.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSDigest.c
index 33798d3833..57a4012034 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSDigest.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSDigest.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2011 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
* limitations under the License.
*/
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.c
index 45dbb7cbd3..1c6cb5be7c 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003-2011 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,13 +13,6 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-
- File: GenLinkedList.c
-
- Contains: implementation of generic linked lists.
-
- Version: 1.0
- Tabs: 4 spaces
*/
#include "GenLinkedList.h"
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.c
index cf8e404637..afba1c66bf 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -64,8 +64,12 @@ 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)); goto exit; }
+ if ((connect(sock, &addr.s, inner_len)) < 0) {
+ if (errno != ENETUNREACH)
+ LogMsg("mDNSPlatformSourceAddrForDest: connect %#a failed errno %d (%s)", dst, errno,
+ strerror(errno));
+ goto exit;
+ }
if ((getsockname(sock, &addr.s, &len)) < 0)
{ LogMsg("mDNSPlatformSourceAddrForDest: getsockname failed errno %d (%s)", errno, strerror(errno)); goto exit; }
@@ -190,10 +194,13 @@ mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, m
if (ident && ident[0] && mDNSPlatformClockDivisor)
syslog(syslog_level, "%8d.%03d: %s", (int)(t/1000), ms, buffer);
else
-#elif APPLE_OSX_mDNSResponder
- mDNSPlatformLogToFile(syslog_level, buffer);
+#endif
+ {
+#if APPLE_OSX_mDNSResponder
+ mDNSPlatformLogToFile(syslog_level, buffer);
#else
- syslog(syslog_level, "%s", buffer);
+ syslog(syslog_level, "%s", buffer);
#endif
+ }
}
}
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PosixDaemon.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PosixDaemon.c
index cfd9d0a30e..55edb0475d 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PosixDaemon.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PosixDaemon.c
@@ -50,7 +50,7 @@ extern int daemon(int, int);
#include "PlatformCommon.h"
#ifndef MDNSD_USER
-#define MDNSD_USER "nobody"
+#define MDNSD_USER "nobody"
#endif
#define CONFIG_FILE "/etc/mdnsd.conf"
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.c
index 94b102ecb7..184de13788 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,14 @@
#define ANON_NSEC3_ITERATIONS 1
+struct AnonInfoResourceRecord_struct
+{
+ ResourceRecord resrec;
+ RData rdatastorage;
+};
+
+typedef struct AnonInfoResourceRecord_struct AnonInfoResourceRecord;
+
mDNSlocal mDNSBool InitializeNSEC3Record(ResourceRecord *rr, const mDNSu8 *AnonData, int len, mDNSu32 salt)
{
const mDNSu8 *ptr;
@@ -118,9 +126,10 @@ mDNSlocal ResourceRecord *ConstructNSEC3Record(const domainname *service, const
mDNSlocal ResourceRecord *CopyNSEC3ResourceRecord(AnonymousInfo *si, const ResourceRecord *rr)
{
- int len;
+ AnonInfoResourceRecord *anonRR;
domainname *name;
- ResourceRecord *nsec3rr;
+ mDNSu32 neededLen;
+ mDNSu32 extraLen;
if (rr->rdlength < MCAST_NSEC3_RDLENGTH)
{
@@ -128,22 +137,26 @@ mDNSlocal ResourceRecord *CopyNSEC3ResourceRecord(AnonymousInfo *si, const Resou
return mDNSNULL;
}
// Allocate space for the name and the rdata along with the ResourceRecord
- len = DomainNameLength(rr->name);
- nsec3rr = mDNSPlatformMemAllocate(sizeof(ResourceRecord) + len + sizeof(RData));
- if (!nsec3rr)
+ neededLen = rr->rdlength + DomainNameLength(rr->name);
+ extraLen = (neededLen > sizeof(RDataBody)) ? (neededLen - sizeof(RDataBody)) : 0;
+ anonRR = (AnonInfoResourceRecord *)mDNSPlatformMemAllocate(sizeof(AnonInfoResourceRecord) + extraLen);
+ if (!anonRR)
return mDNSNULL;
- *nsec3rr = *rr;
- name = (domainname *)((mDNSu8 *)nsec3rr + sizeof(ResourceRecord));
- nsec3rr->name = (const domainname *)name;
+ anonRR->resrec = *rr;
+
+ anonRR->rdatastorage.MaxRDLength = rr->rdlength;
+ mDNSPlatformMemCopy(anonRR->rdatastorage.u.data, rr->rdata->u.data, rr->rdlength);
+
+ name = (domainname *)(anonRR->rdatastorage.u.data + rr->rdlength);
AssignDomainName(name, rr->name);
- nsec3rr->rdata = (RData *)((mDNSu8 *)nsec3rr->name + len);
- mDNSPlatformMemCopy(nsec3rr->rdata->u.data, rr->rdata->u.data, rr->rdlength);
+ anonRR->resrec.name = name;
+ anonRR->resrec.rdata = &anonRR->rdatastorage;
- si->nsec3RR = nsec3rr;
+ si->nsec3RR = (ResourceRecord *)anonRR;
- return nsec3rr;
+ return si->nsec3RR;
}
// When a service is started or a browse is started with the Anonymous data, we allocate a new random
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.h b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.h
index 2f2b4f8c4e..b60812ea0d 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.h
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/dnssec.h b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/dnssec.h
index 1a8d95351b..b770af8de0 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/dnssec.h
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/dnssec.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#ifndef __DNSSEC_H
#define __DNSSEC_H
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNS.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNS.c
index 2f9227eabd..69236e0b88 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNS.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNS.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,7 +47,6 @@
#include "dns_sd.h" // for kDNSServiceFlags* definitions
#if APPLE_OSX_mDNSResponder
-
#include <WebFilterDNS/WebFilterDNS.h>
#if !NO_WCF
@@ -63,6 +62,10 @@ void WCFConnectionDealloc(WCFConnection* c) __attribute__((weak_import));
#define NO_WCF 1
#endif // APPLE_OSX_mDNSResponder
+#if TARGET_OS_EMBEDDED
+#include "Metrics.h"
+#endif
+
// Forward declarations
mDNSlocal void BeginSleepProcessing(mDNS *const m);
mDNSlocal void RetrySPSRegistrations(mDNS *const m);
@@ -80,6 +83,7 @@ mDNSlocal void DeadvertiseAllInterfaceRecords(mDNS *const m);
mDNSlocal void FreeNSECRecords(mDNS *const m, CacheRecord *NSECRecords);
mDNSlocal void mDNSParseNSEC3Records(mDNS *const m, const DNSMessage *const response, const mDNSu8 *end,
const mDNSInterfaceID InterfaceID, CacheRecord **NSEC3Records);
+mDNSlocal mDNSu8 *GetValueForMACAddr(mDNSu8 *ptr, mDNSu8 *limit, mDNSEthAddr *eth);
// ***************************************************************************
@@ -146,10 +150,6 @@ mDNSlocal void SetNextQueryStopTime(mDNS *const m, const DNSQuestion *const q)
{
mDNS_CheckLock(m);
-#if ForceAlerts
- if (m->mDNS_busy != m->mDNS_reentrancy+1) *(long*)0 = 0;
-#endif
-
if (m->NextScheduledStopTime - q->StopTime > 0)
m->NextScheduledStopTime = q->StopTime;
}
@@ -158,10 +158,6 @@ mDNSexport void SetNextQueryTime(mDNS *const m, const DNSQuestion *const q)
{
mDNS_CheckLock(m);
-#if ForceAlerts
- if (m->mDNS_busy != m->mDNS_reentrancy+1) *(long*)0 = 0;
-#endif
-
if (ActiveQuestion(q))
{
// Depending on whether this is a multicast or unicast question we want to set either:
@@ -352,7 +348,7 @@ mDNSlocal CacheGroup *CacheGroupForRecord(const mDNS *const m, const mDNSu32 slo
return(CacheGroupForName(m, slot, rr->namehash, rr->name));
}
-mDNSexport mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr, mDNSBool *myself)
+mDNSexport mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr)
{
NetworkInterfaceInfo *intf;
@@ -363,44 +359,19 @@ mDNSexport mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterface
for (intf = m->HostInterfaces; intf; intf = intf->next)
if (intf->ip.type == addr->type && intf->InterfaceID == InterfaceID && intf->McastTxRx)
if (((intf->ip.ip.v4.NotAnInteger ^ addr->ip.v4.NotAnInteger) & intf->mask.ip.v4.NotAnInteger) == 0)
- {
- if (myself)
- {
- if (mDNSSameIPv4Address(intf->ip.ip.v4, addr->ip.v4))
- *myself = mDNStrue;
- else
- *myself = mDNSfalse;
- if (*myself)
- debugf("mDNS_AddressIsLocalSubnet: IPv4 %#a returning true", addr);
- else
- debugf("mDNS_AddressIsLocalSubnet: IPv4 %#a returning false", addr);
- }
return(mDNStrue);
- }
}
if (addr->type == mDNSAddrType_IPv6)
{
+ if (mDNSv6AddressIsLinkLocal(&addr->ip.v6)) return(mDNStrue);
for (intf = m->HostInterfaces; intf; intf = intf->next)
if (intf->ip.type == addr->type && intf->InterfaceID == InterfaceID && intf->McastTxRx)
if ((((intf->ip.ip.v6.l[0] ^ addr->ip.v6.l[0]) & intf->mask.ip.v6.l[0]) == 0) &&
(((intf->ip.ip.v6.l[1] ^ addr->ip.v6.l[1]) & intf->mask.ip.v6.l[1]) == 0) &&
(((intf->ip.ip.v6.l[2] ^ addr->ip.v6.l[2]) & intf->mask.ip.v6.l[2]) == 0) &&
(((intf->ip.ip.v6.l[3] ^ addr->ip.v6.l[3]) & intf->mask.ip.v6.l[3]) == 0))
- {
- if (myself)
- {
- if (mDNSSameIPv6Address(intf->ip.ip.v6, addr->ip.v6))
- *myself = mDNStrue;
- else
- *myself = mDNSfalse;
- if (*myself)
- debugf("mDNS_AddressIsLocalSubnet: IPv6 %#a returning true", addr);
- else
- debugf("mDNS_AddressIsLocalSubnet: IPv6 %#a returning false", addr);
- }
return(mDNStrue);
- }
}
return(mDNSfalse);
@@ -475,11 +446,20 @@ mDNSexport void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, Re
const mDNSu32 c = q->CNAMEReferrals + 1; // Stash a copy of the new q->CNAMEReferrals value
UDPSocket *sock = q->LocalSocket;
mDNSOpaque16 id = q->TargetQID;
+#if TARGET_OS_EMBEDDED
+ domainname *originalQName;
+#endif
// if there is a message waiting at the socket, we want to process that instead
// of throwing it away. If we have a CNAME response that answers
// both A and AAAA question and while answering it we don't want to throw
// away the response where the actual addresses are present.
+ // This is a stupid hack and we should get rid of it.
+ // The chance of there being a second unicast UDP packet already waiting in the kernel before we’ve
+ // finished processing the previous one is virtually nil, and will only happen by luck on very rare
+ // occasions when running on a machine with a fast network connection and a slow or busy processor.
+ // The idea that we’d rely for correctness on this random chance event occurring is ridiculous.
+ // -- SC
if (mDNSPlatformPeekUDP(m, q->LocalSocket))
{
LogInfo("AnswerQuestionByFollowingCNAME: Preserving UDP socket for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
@@ -508,6 +488,31 @@ mDNSexport void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, Re
LogInfo("AnswerQuestionByFollowingCNAME: %p %##s (%s) following CNAME referral %d for %s",
q, q->qname.c, DNSTypeName(q->qtype), q->CNAMEReferrals, RRDisplayString(m, rr));
+#if TARGET_OS_EMBEDDED
+ if (q->metrics.originalQName)
+ {
+ originalQName = q->metrics.originalQName;
+ q->metrics.originalQName = mDNSNULL;
+ }
+ else
+ {
+ mDNSu16 qNameLen;
+
+ qNameLen = DomainNameLength(&q->qname);
+ if ((qNameLen > 0) && (qNameLen <= MAX_DOMAIN_NAME))
+ {
+ originalQName = mDNSPlatformMemAllocate(qNameLen);
+ if (originalQName)
+ {
+ mDNSPlatformMemCopy(originalQName->c, q->qname.c, qNameLen);
+ }
+ }
+ else
+ {
+ originalQName = mDNSNULL;
+ }
+ }
+#endif
mDNS_StopQuery_internal(m, q); // Stop old query
AssignDomainName(&q->qname, &rr->rdata->u.name); // Update qname
q->qnamehash = DomainNameHashValue(&q->qname); // and namehash
@@ -524,6 +529,9 @@ mDNSexport void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, Re
// Record how many times we've done this. We need to do this *after* mDNS_StartQuery_internal,
// because mDNS_StartQuery_internal re-initializes CNAMEReferrals to zero
q->CNAMEReferrals = c;
+#if TARGET_OS_EMBEDDED
+ q->metrics.originalQName = originalQName;
+#endif
if (sock)
{
// We have a message waiting and that should answer this question.
@@ -933,7 +941,7 @@ mDNSlocal void SetTargetToHostName(mDNS *const m, AuthRecord *const rr)
{
const domainname *const n = SetUnicastTargetToHostName(m, rr);
if (n) newname = n;
- else { target->c[0] = 0; SetNewRData(&rr->resrec, mDNSNULL, 0); return; }
+ else { if (target) target->c[0] = 0; SetNewRData(&rr->resrec, mDNSNULL, 0); return; }
}
if (target && SameDomainName(target, newname))
@@ -1133,26 +1141,61 @@ mDNSlocal AuthRecord *CheckAuthSameRecord(AuthHash *r, AuthRecord *rr)
mDNSlocal void DecrementAutoTargetServices(mDNS *const m, AuthRecord *const rr)
{
+ if (RRLocalOnly(rr))
+ {
+ // A sanity check, this should be prevented in calling code.
+ LogInfo("DecrementAutoTargetServices: called for RRLocalOnly() record: %s", ARDisplayString(m, rr));
+ return;
+ }
+
if (!AuthRecord_uDNS(rr) && rr->resrec.rrtype == kDNSType_SRV && rr->AutoTarget == Target_AutoHost)
{
- m->AutoTargetServices--;
- LogInfo("DecrementAutoTargetServices: AutoService Record %s, AutoTargetServices %d", ARDisplayString(m, rr), m->AutoTargetServices);
- if (!m->AutoTargetServices)
+ // If about to get rid of the last advertised service
+ if (m->AutoTargetServices == 1)
DeadvertiseAllInterfaceRecords(m);
+
+ m->AutoTargetServices--;
+ LogInfo("DecrementAutoTargetServices: AutoTargetServices %d Record %s", m->AutoTargetServices, ARDisplayString(m, rr));
+ }
+
+#if TARGET_OS_WATCH
+ if (!AuthRecord_uDNS(rr))
+ {
+ if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
+ m->NetworkChanged = m->timenow;
+ m->NumAllInterfaceRecords--;
+ LogInfo("DecrementAutoTargetServices: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %s",
+ m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, ARDisplayString(m, rr));
}
+#endif
}
mDNSlocal void IncrementAutoTargetServices(mDNS *const m, AuthRecord *const rr)
{
- if (!AuthRecord_uDNS(rr) && rr->resrec.rrtype == kDNSType_SRV && rr->AutoTarget == Target_AutoHost)
+ if (RRLocalOnly(rr))
+ {
+ // A sanity check, this should be prevented in calling code.
+ LogInfo("IncrementAutoTargetServices: called for RRLocalOnly() record: %s", ARDisplayString(m, rr));
+ return;
+ }
+
+#if TARGET_OS_WATCH
+ if (!AuthRecord_uDNS(rr))
{
- int count = m->AutoTargetServices;
+ m->NumAllInterfaceRecords++;
+ LogInfo("IncrementAutoTargetServices: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %s",
+ m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, ARDisplayString(m, rr));
+ if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
+ m->NetworkChanged = m->timenow;
+ }
+#endif
- // Bump up before calling AdvertiseAllInterfaceRecords. AdvertiseInterface
- // returns without doing anything if the count is zero.
+ if (!AuthRecord_uDNS(rr) && rr->resrec.rrtype == kDNSType_SRV && rr->AutoTarget == Target_AutoHost)
+ {
m->AutoTargetServices++;
- LogInfo("IncrementAutoTargetServices: AutoService Record %s, AutoTargetServices %d", ARDisplayString(m, rr), m->AutoTargetServices);
- if (!count)
+ LogInfo("IncrementAutoTargetServices: AutoTargetServices %d Record %s", m->AutoTargetServices, ARDisplayString(m, rr));
+ // If this is the first advertised service
+ if (m->AutoTargetServices == 1)
AdvertiseAllInterfaceRecords(m);
}
}
@@ -1378,6 +1421,7 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
// (kDNSRecordTypeDeregistering) so that we deliver RMV events to the application. But this causes more
// complications and not clear whether there are any benefits. See rdar:9304275 for details.
// Hence, just bail out.
+ // This comment is doesn’t make any sense. -- SC
if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
{
if (CheckAuthRecordConflict(&m->rrauth, rr))
@@ -1443,11 +1487,12 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
{
AuthGroup *ag;
ag = InsertAuthRecord(m, &m->rrauth, rr);
- if (ag && !ag->NewLocalOnlyRecords) {
+ if (ag && !ag->NewLocalOnlyRecords)
+ {
m->NewLocalOnlyRecords = mDNStrue;
ag->NewLocalOnlyRecords = rr;
}
- // No probing for LocalOnly records, Acknowledge them right away
+ // No probing for LocalOnly records; acknowledge them right away
if (rr->resrec.RecordType == kDNSRecordTypeUnique) rr->resrec.RecordType = kDNSRecordTypeVerified;
AcknowledgeRecord(m, rr);
return(mStatus_NoError);
@@ -1459,15 +1504,15 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
}
}
- // If this is a keepalive record, fetch the MAC address of the remote host.
+ // If this is a non-sleep proxy keepalive record, fetch the MAC address of the remote host.
// This is used by the in-NIC proxy to send the keepalive packets.
- if (mDNS_KeepaliveRecord(&rr->resrec))
+ if (!rr->WakeUp.HMAC.l[0] && mDNS_KeepaliveRecord(&rr->resrec))
{
+ mDNSAddr raddr;
// Set the record type to known unique to prevent probing keep alive records.
// Also make sure we do not announce the keepalive records.
rr->resrec.RecordType = kDNSRecordTypeKnownUnique;
rr->AnnounceCount = 0;
- mDNSAddr raddr;
getKeepaliveRaddr(m, rr, &raddr);
// This is an asynchronous call. Once the remote MAC address is available, helper will schedule an
// asynchronous task to update the resource record
@@ -1476,8 +1521,9 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
if (!AuthRecord_uDNS(rr)) // This check is superfluous, given that for unicast records we (currently) bail out above
{
- // We have inserted the record in the list. See if we have to advertise the A/AAAA,HINFO,PTR records.
+ // We have inserted the record in the list. See if we have to advertise the A/AAAA, HINFO, PTR records.
IncrementAutoTargetServices(m, rr);
+
// For records that are not going to probe, acknowledge them right away
if (rr->resrec.RecordType != kDNSRecordTypeUnique && rr->resrec.RecordType != kDNSRecordTypeDeregistering)
AcknowledgeRecord(m, rr);
@@ -2373,8 +2419,8 @@ mDNSlocal void SendResponses(mDNS *const m)
LogSPS("SendResponses: Sending wakeup %2d for %.6a %s", rr->AnnounceCount-3, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
SendWakeup(m, rr->resrec.InterfaceID, &rr->WakeUp.IMAC, &rr->WakeUp.password);
for (r2 = rr; r2; r2=r2->next)
- if (r2->AnnounceCount && r2->resrec.InterfaceID == rr->resrec.InterfaceID && mDNSSameEthAddress(&r2->WakeUp.IMAC, &rr->WakeUp.IMAC) &&
- !mDNSSameEthAddress(&zeroEthAddr, &r2->WakeUp.HMAC))
+ if ((r2->resrec.RecordType == kDNSRecordTypeDeregistering) && r2->AnnounceCount && (r2->resrec.InterfaceID == rr->resrec.InterfaceID) &&
+ mDNSSameEthAddress(&r2->WakeUp.IMAC, &rr->WakeUp.IMAC) && !mDNSSameEthAddress(&zeroEthAddr, &r2->WakeUp.HMAC))
{
// For now we only want to send a single Unsolicited Neighbor Advertisement restoring the address to the original
// owner, because these packets can cause some IPv6 stacks to falsely conclude that there's an address conflict.
@@ -2544,7 +2590,7 @@ mDNSlocal void SendResponses(mDNS *const m)
if ((rr->SendRNow == intf->InterfaceID) &&
((rr->resrec.InterfaceID == mDNSInterface_Any) && !mDNSPlatformValidRecordForInterface(rr, intf)))
{
- LogInfo("SendResponses: Not sending %s, on %s", ARDisplayString(m, rr), InterfaceNameForID(m, rr->SendRNow));
+ // LogInfo("SendResponses: Not sending %s, on %s", ARDisplayString(m, rr), InterfaceNameForID(m, rr->SendRNow));
rr->SendRNow = GetNextActiveInterfaceID(intf);
}
else if (rr->SendRNow == intf->InterfaceID)
@@ -2929,10 +2975,10 @@ mDNSexport mStatus mDNS_Reconfirm_internal(mDNS *const m, CacheRecord *const rr,
// BuildQuestion puts a question into a DNS Query packet and if successful, updates the value of queryptr.
// It also appends to the list of known answer records that need to be included,
// and updates the forcast for the size of the known answer section.
-mDNSlocal mDNSBool BuildQuestion(mDNS *const m, DNSMessage *query, mDNSu8 **queryptr, DNSQuestion *q,
- CacheRecord ***kalistptrptr, mDNSu32 *answerforecast)
+mDNSlocal mDNSBool BuildQuestion(mDNS *const m, const NetworkInterfaceInfo *intf, DNSMessage *query, mDNSu8 **queryptr,
+ DNSQuestion *q, CacheRecord ***kalistptrptr, mDNSu32 *answerforecast)
{
- mDNSBool ucast = (q->LargeAnswers || q->RequestUnicast) && m->CanReceiveUnicastOn5353;
+ mDNSBool ucast = (q->LargeAnswers || q->RequestUnicast) && m->CanReceiveUnicastOn5353 && intf->SupportsUnicastMDNSResponse;
mDNSu16 ucbit = (mDNSu16)(ucast ? kDNSQClass_UnicastResponse : 0);
const mDNSu8 *const limit = query->data + NormalMaxDNSMessageData;
mDNSu8 anoninfo_space = q->AnonInfo ? AnonInfoSpace(q->AnonInfo) : 0;
@@ -3072,27 +3118,27 @@ mDNSlocal const CacheRecord *FindSPSInCache1(mDNS *const m, const DNSQuestion *c
#endif // SPC_DISABLED
}
-mDNSlocal void CheckAndSwapSPS(const CacheRecord *sps1, const CacheRecord *sps2)
+mDNSlocal void CheckAndSwapSPS(const CacheRecord **sps1, const CacheRecord **sps2)
{
const CacheRecord *swap_sps;
mDNSu32 metric1, metric2;
- if (!sps1 || !sps2) return;
- metric1 = SPSMetric(sps1->resrec.rdata->u.name.c);
- metric2 = SPSMetric(sps2->resrec.rdata->u.name.c);
- if (!SPSFeatures(sps1->resrec.rdata->u.name.c) && SPSFeatures(sps2->resrec.rdata->u.name.c) && (metric2 >= metric1))
+ if (!(*sps1) || !(*sps2)) return;
+ metric1 = SPSMetric((*sps1)->resrec.rdata->u.name.c);
+ metric2 = SPSMetric((*sps2)->resrec.rdata->u.name.c);
+ if (!SPSFeatures((*sps1)->resrec.rdata->u.name.c) && SPSFeatures((*sps2)->resrec.rdata->u.name.c) && (metric2 >= metric1))
{
- swap_sps = sps1;
- sps1 = sps2;
- sps2 = swap_sps;
+ swap_sps = *sps1;
+ *sps1 = *sps2;
+ *sps2 = swap_sps;
}
}
mDNSlocal void ReorderSPSByFeature(const CacheRecord *sps[3])
{
- CheckAndSwapSPS(sps[0], sps[1]);
- CheckAndSwapSPS(sps[0], sps[2]);
- CheckAndSwapSPS(sps[1], sps[2]);
+ CheckAndSwapSPS(&sps[0], &sps[1]);
+ CheckAndSwapSPS(&sps[0], &sps[2]);
+ CheckAndSwapSPS(&sps[1], &sps[2]);
}
@@ -3136,7 +3182,7 @@ mDNSlocal mDNSBool SuppressOnThisInterface(const DupSuppressInfo ds[DupSuppressI
return(mDNSfalse);
}
-mDNSlocal int RecordDupSuppressInfo(DupSuppressInfo ds[DupSuppressInfoSize], mDNSs32 Time, mDNSInterfaceID InterfaceID, mDNSs32 Type)
+mDNSlocal void RecordDupSuppressInfo(DupSuppressInfo ds[DupSuppressInfoSize], mDNSs32 Time, mDNSInterfaceID InterfaceID, mDNSs32 Type)
{
int i, j;
@@ -3156,8 +3202,6 @@ mDNSlocal int RecordDupSuppressInfo(DupSuppressInfo ds[DupSuppressInfoSize], mDN
ds[i].Time = Time;
ds[i].InterfaceID = InterfaceID;
ds[i].Type = Type;
-
- return(i);
}
mDNSlocal void mDNSSendWakeOnResolve(mDNS *const m, DNSQuestion *q)
@@ -3175,7 +3219,6 @@ mDNSlocal void mDNSSendWakeOnResolve(mDNS *const m, DNSQuestion *q)
// Split MAC@IPAddress and pass them separately
len = d->c[0];
- i = 1;
cnt = 0;
for (i = 1; i < len; i++)
{
@@ -3570,7 +3613,7 @@ mDNSlocal void SendQueries(mDNS *const m)
}
// If we're suppressing this question, or we successfully put it, update its SendQNow state
else if ((Suppress = SuppressOnThisInterface(q->DupSuppress, intf)) ||
- BuildQuestion(m, &m->omsg, &queryptr, q, &kalistptr, &answerforecast))
+ BuildQuestion(m, intf, &m->omsg, &queryptr, q, &kalistptr, &answerforecast))
{
// We successfully added the question to the packet. Make sure that
// we also send the NSEC3 record if required. BuildQuestion accounted for
@@ -3594,7 +3637,7 @@ mDNSlocal void SendQueries(mDNS *const m)
q->WakeOnResolveCount--;
}
- // use brackground traffic class if any included question requires it
+ // use background traffic class if any included question requires it
if (q->UseBackgroundTrafficClass)
{
useBackgroundTrafficClass = mDNStrue;
@@ -3607,7 +3650,7 @@ mDNSlocal void SendQueries(mDNS *const m)
for (ar = m->ResourceRecords; ar; ar=ar->next)
if (ar->SendRNow == intf->InterfaceID)
{
- mDNSBool ucast = (ar->ProbeCount >= DefaultProbeCountForTypeUnique-1) && m->CanReceiveUnicastOn5353;
+ mDNSBool ucast = (ar->ProbeCount >= DefaultProbeCountForTypeUnique-1) && m->CanReceiveUnicastOn5353 && intf->SupportsUnicastMDNSResponse;
mDNSu16 ucbit = (mDNSu16)(ucast ? kDNSQClass_UnicastResponse : 0);
const mDNSu8 *const limit = m->omsg.data + (m->omsg.h.numQuestions ? NormalMaxDNSMessageData : AbsoluteMaxDNSMessageData);
// We forecast: compressed name (2) type (2) class (2) TTL (4) rdlength (2) rdata (n)
@@ -3905,6 +3948,31 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
return;
}
+#if TARGET_OS_EMBEDDED
+ if ((AddRecord == QC_add) && Question_uDNS(q) && (!q->metrics.answered || (q->metrics.querySendCount > 0)))
+ {
+ uDNSMetrics * metrics;
+ const domainname * queryName;
+ mDNSu32 responseLatencyMs;
+ mDNSBool isForCellular;
+
+ metrics = &q->metrics;
+ queryName = metrics->originalQName ? metrics->originalQName : &q->qname;
+ if (metrics->querySendCount > 0)
+ {
+ responseLatencyMs = ((m->timenow - metrics->firstQueryTime) * 1000) / mDNSPlatformOneSecond;
+ }
+ else
+ {
+ responseLatencyMs = 0;
+ }
+ isForCellular = (q->qDNSServer && q->qDNSServer->cellIntf);
+
+ MetricsUpdateUDNSStats(queryName, mDNStrue, metrics->querySendCount, responseLatencyMs, isForCellular);
+ metrics->answered = mDNStrue;
+ metrics->querySendCount = 0;
+ }
+#endif
// Note: Use caution here. In the case of records with rr->DelayDelivery set, AnswerCurrentQuestionWithResourceRecord(... mDNStrue)
// may be called twice, once when the record is received, and again when it's time to notify local clients.
// If any counters or similar are added here, care must be taken to ensure that they are not double-incremented by this.
@@ -4086,6 +4154,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
@@ -4108,7 +4177,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;
@@ -4898,7 +4967,7 @@ mDNSexport mDNSs32 mDNS_TimeNow(const mDNS *const m)
// had its Sleep Proxy client list change, and defer to actual BPF reconfiguration to mDNS_Execute().
// (GetNextScheduledEvent() returns "now" when m->SPSProxyListChanged is set)
#define SetSPSProxyListChanged(X) do { \
- if (m->SPSProxyListChanged && m->SPSProxyListChanged != (X)) mDNSPlatformUpdateProxyList(m, m->SPSProxyListChanged); \
+ if (m->SPSProxyListChanged && m->SPSProxyListChanged != (X)) mDNSPlatformUpdateProxyList(m, m->SPSProxyListChanged); \
m->SPSProxyListChanged = (X); } while(0)
// Called from mDNS_Execute() to expire stale proxy records
@@ -5572,26 +5641,34 @@ mDNSexport void mDNS_UpdateAllowSleep(mDNS *const m)
break;
}
- // Disallow sleep if there is no sleep proxy server
- const CacheRecord *cr = FindSPSInCache1(m, &intf->NetWakeBrowse, mDNSNULL, mDNSNULL);
- if ( cr == mDNSNULL)
- {
- allowSleep = mDNSfalse;
- mDNS_snprintf(reason, sizeof(reason), "No sleep proxy server on %s", intf->ifname);
- LogInfo("mDNS_UpdateAllowSleep: Sleep disabled because %s has no sleep proxy server", intf->ifname);
- break;
- }
- else if (m->SPSType != 0)
+ // If the interface can be an in-NIC Proxy, we should check if it can accomodate all the records
+ // that will be offloaded. If not, we should prevent sleep.
+ // This check will be possible once the lower layers provide an API to query the space available for offloads on the NIC.
+#if APPLE_OSX_mDNSResponder
+ if (!SupportsInNICProxy(intf))
+#endif
{
- mDNSu32 mymetric = LocalSPSMetric(m);
- mDNSu32 metric = SPSMetric(cr->resrec.rdata->u.name.c);
- if (metric >= mymetric)
+ // Disallow sleep if there is no sleep proxy server
+ const CacheRecord *cr = FindSPSInCache1(m, &intf->NetWakeBrowse, mDNSNULL, mDNSNULL);
+ if ( cr == mDNSNULL)
{
allowSleep = mDNSfalse;
- mDNS_snprintf(reason, sizeof(reason), "No sleep proxy server with better metric on %s", intf->ifname);
- LogInfo("mDNS_UpdateAllowSleep: Sleep disabled because %s has no sleep proxy server with a better metric", intf->ifname);
+ mDNS_snprintf(reason, sizeof(reason), "No sleep proxy server on %s", intf->ifname);
+ LogInfo("mDNS_UpdateAllowSleep: Sleep disabled because %s has no sleep proxy server", intf->ifname);
break;
}
+ else if (m->SPSType != 0)
+ {
+ mDNSu32 mymetric = LocalSPSMetric(m);
+ mDNSu32 metric = SPSMetric(cr->resrec.rdata->u.name.c);
+ if (metric >= mymetric)
+ {
+ allowSleep = mDNSfalse;
+ mDNS_snprintf(reason, sizeof(reason), "No sleep proxy server with better metric on %s", intf->ifname);
+ LogInfo("mDNS_UpdateAllowSleep: Sleep disabled because %s has no sleep proxy server with a better metric", intf->ifname);
+ break;
+ }
+ }
}
}
}
@@ -5622,7 +5699,7 @@ mDNSlocal mDNSBool mDNSUpdateOkToSend(mDNS *const m, AuthRecord *rr, NetworkInte
// updateid and we should have returned from above.
//
// Note: scopeid is the same as intf->InterfaceID. It is passed in so that we don't have to call the
- // platform function to extract the value from "intf" everytime.
+ // platform function to extract the value from "intf" every time.
if ((scopeid >= (sizeof(rr->updateIntID) * mDNSNBBY) || bit_get_opaque64(rr->updateIntID, scopeid)) &&
(!rr->resrec.InterfaceID || rr->resrec.InterfaceID == intf->InterfaceID))
@@ -5633,35 +5710,41 @@ mDNSlocal mDNSBool mDNSUpdateOkToSend(mDNS *const m, AuthRecord *rr, NetworkInte
mDNSexport void UpdateRMACCallback(mDNS *const m, void *context)
{
- IPAddressMACMapping *addrmap = (IPAddressMACMapping *)context ;
- m->CurrentRecord = m->ResourceRecords;
-
- if (!addrmap)
- {
- LogMsg("UpdateRMACCallback: Address mapping is NULL");
- return;
- }
-
- while (m->CurrentRecord)
- {
- AuthRecord *rr = m->CurrentRecord;
- // If this is a keepalive record and the remote IP address matches, update the RData
- if (mDNS_KeepaliveRecord(&rr->resrec))
- {
- mDNSAddr raddr;
- getKeepaliveRaddr(m, rr, &raddr);
- if (mDNSSameAddress(&raddr, &addrmap->ipaddr))
- {
- UpdateKeepaliveRData(m, rr, mDNSNULL, mDNStrue, (char *)(addrmap->ethaddr));
- }
- }
- m->CurrentRecord = rr->next;
- }
-
- if (addrmap)
- {
- mDNSPlatformMemFree(addrmap);
- }
+ IPAddressMACMapping *addrmap = (IPAddressMACMapping *)context ;
+ m->CurrentRecord = m->ResourceRecords;
+
+ if (!addrmap)
+ {
+ LogMsg("UpdateRMACCallback: Address mapping is NULL");
+ return;
+ }
+
+ while (m->CurrentRecord)
+ {
+ AuthRecord *rr = m->CurrentRecord;
+ // If this is a non-sleep proxy keepalive record and the remote IP address matches, update the RData
+ if (!rr->WakeUp.HMAC.l[0] && mDNS_KeepaliveRecord(&rr->resrec))
+ {
+ mDNSAddr raddr;
+ getKeepaliveRaddr(m, rr, &raddr);
+ if (mDNSSameAddress(&raddr, &addrmap->ipaddr))
+ {
+ // Update the MAC address only if it is not a zero MAC address
+ mDNSEthAddr macAddr;
+ mDNSu8 *ptr = GetValueForMACAddr((mDNSu8 *)(addrmap->ethaddr), (mDNSu8 *) (addrmap->ethaddr + sizeof(addrmap->ethaddr)), &macAddr);
+ if (ptr != mDNSNULL && !mDNSEthAddressIsZero(macAddr))
+ {
+ UpdateKeepaliveRData(m, rr, mDNSNULL, mDNStrue, (char *)(addrmap->ethaddr));
+ }
+ }
+ }
+ m->CurrentRecord = rr->next;
+ }
+
+ if (addrmap)
+ {
+ mDNSPlatformMemFree(addrmap);
+ }
}
mDNSexport mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkInterfaceInfo *const intf, mDNSBool updateMac, char *ethAddr)
@@ -6128,29 +6211,49 @@ mDNSexport mDNSBool mDNSCoreHaveAdvertisedMulticastServices(mDNS *const m)
return mDNSfalse;
}
+#define WAKE_ONLY_SERVICE 1
+#define AC_ONLY_SERVICE 2
+
#ifdef APPLE_OSX_mDNSResponder
-// This function is used only in the case of local NIC proxy. For external
-// sleep proxy server, we do this in SPSInitRecordsBeforeUpdate when we
-// walk the resource records.
-mDNSlocal void SendGoodbyesForWakeOnlyService(mDNS *const m, mDNSBool *WakeOnlyService)
+mDNSlocal void SendGoodbyesForSelectServices(mDNS *const m, mDNSBool *servicePresent, mDNSu32 serviceType)
{
AuthRecord *rr;
-
- *WakeOnlyService = mDNSfalse;
+ *servicePresent = mDNSfalse;
// Mark all the records we need to deregister and send them
for (rr = m->ResourceRecords; rr; rr=rr->next)
{
- if ((rr->AuthFlags & AuthFlagsWakeOnly) &&
- rr->resrec.RecordType == kDNSRecordTypeShared && rr->RequireGoodbye)
+ // If the service type is wake only service and the auth flags match and requires a goodbye
+ // OR if the service type is AC only and it is not a keepalive record,
+ // mark the records we need to deregister and send them
+ if ((serviceType == WAKE_ONLY_SERVICE && (rr->AuthFlags & AuthFlagsWakeOnly) &&
+ rr->resrec.RecordType == kDNSRecordTypeShared && rr->RequireGoodbye) ||
+ (serviceType == AC_ONLY_SERVICE && !mDNS_KeepaliveRecord(&rr->resrec)))
{
rr->ImmedAnswer = mDNSInterfaceMark;
- *WakeOnlyService = mDNStrue;
+ *servicePresent = mDNStrue;
}
}
}
+#endif
+
+#ifdef APPLE_OSX_mDNSResponder
+// This function is used only in the case of local NIC proxy. For external
+// sleep proxy server, we do this in SPSInitRecordsBeforeUpdate when we
+// walk the resource records.
+mDNSlocal void SendGoodbyesForWakeOnlyService(mDNS *const m, mDNSBool *WakeOnlyService)
+{
+ return SendGoodbyesForSelectServices(m, WakeOnlyService, WAKE_ONLY_SERVICE);
+}
#endif // APPLE_OSx_mDNSResponder
+#ifdef APPLE_OSX_mDNSResponder
+mDNSlocal void SendGoodbyesForACOnlyServices(mDNS *const m, mDNSBool *acOnlyService)
+{
+ return SendGoodbyesForSelectServices(m, acOnlyService, AC_ONLY_SERVICE);
+}
+#endif
+
mDNSlocal void SendSleepGoodbyes(mDNS *const m, mDNSBool AllInterfaces, mDNSBool unicast)
{
AuthRecord *rr;
@@ -6246,6 +6349,7 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
{
mDNSBool SendGoodbyes = mDNStrue;
mDNSBool WakeOnlyService = mDNSfalse;
+ mDNSBool ACOnlyService = mDNSfalse;
mDNSBool invokeKACallback = mDNStrue;
const CacheRecord *sps[3] = { mDNSNULL };
mDNSOpaque64 updateIntID = zeroOpaque64;
@@ -6302,9 +6406,12 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
#if APPLE_OSX_mDNSResponder
else if (SupportsInNICProxy(intf))
{
- if (ActivateLocalProxy(m, intf) == mStatus_NoError)
+ mDNSBool keepaliveOnly = mDNSfalse;
+ if (ActivateLocalProxy(m, intf, &keepaliveOnly) == mStatus_NoError)
{
SendGoodbyesForWakeOnlyService(m, &WakeOnlyService);
+ if (keepaliveOnly)
+ SendGoodbyesForACOnlyServices(m, &ACOnlyService);
SendGoodbyes = mDNSfalse;
invokeKACallback = mDNSfalse;
LogSPS("BeginSleepProcessing: %-6s using local proxy", intf->ifname);
@@ -6348,9 +6455,9 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
{
#if ForceAlerts
if (intf->SPSAddr[i].type)
- { LogMsg("BeginSleepProcessing: %s %d intf->SPSAddr[i].type %d", intf->ifname, i, intf->SPSAddr[i].type); *(long*)0 = 0; }
+ LogFatalError("BeginSleepProcessing: %s %d intf->SPSAddr[i].type %d", intf->ifname, i, intf->SPSAddr[i].type);
if (intf->NetWakeResolve[i].ThisQInterval >= 0)
- { LogMsg("BeginSleepProcessing: %s %d intf->NetWakeResolve[i].ThisQInterval %d", intf->ifname, i, intf->NetWakeResolve[i].ThisQInterval); *(long*)0 = 0; }
+ LogFatalError("BeginSleepProcessing: %s %d intf->NetWakeResolve[i].ThisQInterval %d", intf->ifname, i, intf->NetWakeResolve[i].ThisQInterval);
#endif
intf->SPSAddr[i].type = mDNSAddrType_None;
if (intf->NetWakeResolve[i].ThisQInterval >= 0) mDNS_StopQuery(m, &intf->NetWakeResolve[i]);
@@ -6410,10 +6517,10 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
LogSPS("BeginSleepProcessing: Not registering with Sleep Proxy Server on all interfaces");
SendSleepGoodbyes(m, mDNSfalse, mDNSfalse);
}
- else if (WakeOnlyService)
+ else if (WakeOnlyService || ACOnlyService)
{
// If we saw WakeOnly service above, send the goodbyes now.
- LogSPS("BeginSleepProcessing: Sending goodbyes for WakeOnlyServices");
+ LogSPS("BeginSleepProcessing: Sending goodbyes for %s", WakeOnlyService? "WakeOnlyService" : "AC Only Service");
SendResponses(m);
}
}
@@ -6487,11 +6594,7 @@ mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleep)
{
m->SleepState = SleepState_Awake;
m->SleepSeqNum++;
- // If the machine wakes and then immediately tries to sleep again (e.g. a maintenance wake)
- // then we enforce a minimum delay of 16 seconds before we begin sleep processing.
- // This is to allow time for the Ethernet link to come up, DHCP to get an address, mDNS to issue queries, etc.,
- // before we make our determination of whether there's a Sleep Proxy out there we should register with.
- m->DelaySleep = NonZeroTime(m->timenow + mDNSPlatformOneSecond * 16);
+ m->DelaySleep = 0;
}
if (m->SPSState == 3)
@@ -7117,7 +7220,7 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
const mDNSAddr *srcaddr, const mDNSInterfaceID InterfaceID, mDNSBool LegacyQuery, mDNSBool QueryWasMulticast,
mDNSBool QueryWasLocalUnicast, DNSMessage *const response)
{
- mDNSBool FromLocalSubnet = srcaddr && mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr, mDNSNULL);
+ mDNSBool FromLocalSubnet = srcaddr && mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr);
AuthRecord *ResponseRecords = mDNSNULL;
AuthRecord **nrp = &ResponseRecords;
@@ -7667,9 +7770,9 @@ exit:
DNSQuestion *q = DupQuestions;
DupQuestions = q->NextInDQList;
q->NextInDQList = mDNSNULL;
- i = RecordDupSuppressInfo(q->DupSuppress, m->timenow, InterfaceID, srcaddr->type);
- debugf("ProcessQuery: Recorded DSI for %##s (%s) on %p/%s %d", q->qname.c, DNSTypeName(q->qtype), InterfaceID,
- srcaddr->type == mDNSAddrType_IPv4 ? "v4" : "v6", i);
+ RecordDupSuppressInfo(q->DupSuppress, m->timenow, InterfaceID, srcaddr->type);
+ debugf("ProcessQuery: Recorded DSI for %##s (%s) on %p/%s", q->qname.c, DNSTypeName(q->qtype), InterfaceID,
+ srcaddr->type == mDNSAddrType_IPv4 ? "v4" : "v6");
}
if (McastNSEC3Records)
@@ -7687,7 +7790,7 @@ mDNSlocal void mDNSCoreReceiveQuery(mDNS *const m, const DNSMessage *const msg,
{
mDNSu8 *responseend = mDNSNULL;
mDNSBool QueryWasLocalUnicast = srcaddr && dstaddr &&
- !mDNSAddrIsDNSMulticast(dstaddr) && mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr, mDNSNULL);
+ !mDNSAddrIsDNSMulticast(dstaddr) && mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr);
if (!InterfaceID && dstaddr && mDNSAddrIsDNSMulticast(dstaddr))
{
@@ -7779,10 +7882,10 @@ mDNSlocal DNSQuestion *ExpectingUnicastResponseForRecord(mDNS *const m,
mDNSIPPort srcp;
if (!tcp)
{
- if (q->LocalSocket)
- srcp = q->LocalSocket->port;
+ if (q->LocalSocket)
+ srcp = q->LocalSocket->port;
else
- srcp = zeroIPPort;
+ srcp = zeroIPPort;
}
else
{
@@ -7808,111 +7911,6 @@ mDNSlocal DNSQuestion *ExpectingUnicastResponseForRecord(mDNS *const m,
return(mDNSNULL);
}
-// Return a pointer to the primary service name, skipping subtype name if present.
-mDNSlocal const domainname *getPrimaryServiceName(const domainname *domainName)
-{
- const domainname *primaryName = domainName;
- const domainname *subName = SkipLeadingLabels(domainName, 1);
-
- if (SameDomainLabel(subName->c, (const mDNSu8 *)mDNSSubTypeLabel))
- {
- // skip "<sub type name>._sub" portion of name
- primaryName = SkipLeadingLabels(domainName, 2);
- debugf("getPrimaryServiceName: returning %##s for _sub type", primaryName);
- }
-
- return primaryName;
-}
-
-// This function is not called if the packet is from us, which implies that we accept all multicast packets coming from us.
-mDNSlocal mDNSBool ExpectingMulticastResponseForRecord(mDNS *const m, CacheRecord *rr, const mDNSAddr *srcaddr, mDNSBool recordAccepted,
- CacheRecord **McastNSEC3Records)
-{
- DNSQuestion *q;
-
- // Accept A and AAAA if we accepted something before in the same packet as most likely related to the
- // service records that we may have accepted.
- if (recordAccepted && (rr->resrec.rrtype == kDNSType_A || rr->resrec.rrtype == kDNSType_AAAA))
- {
- LogInfo("ExpectingMulticastResponseForRecord:A:AAAA: accepting %s, from %#a due to same packet %d", CRDisplayString(m, rr), srcaddr, m->PktNum);
- return mDNStrue;
- }
- for (q = m->Questions; q; q=q->next)
- {
- if (!q->DuplicateOf && mDNSOpaque16IsZero(q->TargetQID))
- {
- mDNSBool ret;
- // 1. If a resource record answers question, cache it. This also will cache NSECs if it asserts
- // non-existence of q->qtype. If we have any matching NSEC3 Records for the question, send
- // it along with the resource record. Do it only for questions that are expecting to
- // discover only its peers (q->AnonInfo not NULL)
- if (q->AnonInfo && McastNSEC3Records && !rr->resrec.AnonInfo)
- {
- InitializeAnonInfoForCR(m, McastNSEC3Records, rr);
- }
- ret = ResourceRecordAnswersQuestion(&rr->resrec, q);
- if (ret)
- {
- // The record and the question belong to the same subset. Set the
- // anonymous data in the cache record.
- if (q->AnonInfo && rr->resrec.AnonInfo)
- {
- SetAnonData(q, &rr->resrec, mDNSfalse);
- }
- LogInfo("ExpectingMulticastResponseForRecord: Name and Type match, accepting %s, from %#a", CRDisplayString(m, rr), srcaddr);
- if (rr->resrec.rrtype == kDNSType_NSEC)
- LogInfo("ExpectingMulticastResponseForRecord: record %s, question %##s (%s)", CRDisplayString(m, rr), q->qname.c, DNSTypeName(q->qtype));
- return mDNStrue;
- }
- if (rr->resrec.rrtype == kDNSType_SRV || rr->resrec.rrtype == kDNSType_TXT)
- {
- // Point to the service type in the record name
- const domainname *name = SkipLeadingLabels(rr->resrec.name, 1);
-
- // If question is for a sub type, just compare against the primary service type
- const domainname *primaryName = getPrimaryServiceName(&q->qname);
-
- // 2. If the SRV or TXT record matches the service name, then cache it. If the TXT or SRV record is
- // before the PTR record in the packet, PTR record may not be in the cache yet and hence the logic
- // in (3) below will fail to cache it.
- if (q->qtype == kDNSType_PTR && name && SameDomainName(primaryName, name))
- {
- LogInfo("ExpectingMulticastResponseForRecord: Accepting %s due to PTR match, question %##s from %#a, pktnum %d",
- CRDisplayString(m, rr), q->qname.c, srcaddr, m->PktNum);
- return mDNStrue;
- }
-
- if (name)
- {
- const mDNSu32 slot = HashSlot(name);
- const mDNSu32 namehash = DomainNameHashValue(name);
- CacheGroup *cg = CacheGroupForName(m, slot, namehash, name);
- CacheRecord *cr;
-
- // 3. Same as in (2), but look in the cache in case we don't have the PTR question.
-
- for (cr = cg ? cg->members : mDNSNULL; cr; cr=cr->next)
- {
- if (cr->resrec.rrtype == kDNSType_PTR)
- {
- primaryName = getPrimaryServiceName(cr->resrec.name);
-
- if (SameDomainName(primaryName, name))
- {
- LogInfo("ExpectingMulticastResponseForRecord: accepting %s, from %#a, pktnum %d",
- CRDisplayString(m, rr), srcaddr, m->PktNum);
- return mDNStrue;
- }
- }
- }
- }
- }
- }
- }
- debugf("ExpectingMulticastResponseForRecord: discarding %s, from %#a, pktnum %d", CRDisplayString(m, rr), srcaddr, m->PktNum);
- return(mDNSfalse);
-}
-
// Certain data types need more space for in-memory storage than their in-packet rdlength would imply
// Currently this applies only to rdata types containing more than one domainname,
// or types where the domainname is not the last item in the structure.
@@ -8458,7 +8456,8 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
name = (const domainname *)(name->c + 1 + name->c[0]);
hash = DomainNameHashValue(name);
slot = HashSlot(name);
- cg = CacheGroupForName(m, slot, hash, name);
+ // For now, we don't need to update cg here, because we'll do it again immediately, back up at the start of this loop
+ //cg = CacheGroupForName(m, slot, hash, name);
}
}
}
@@ -8660,7 +8659,7 @@ mDNSlocal CacheRecord* mDNSCoreReceiveCacheCheck(mDNS *const m, const DNSMessage
mDNSlocal void mDNSParseNSEC3Records(mDNS *const m, const DNSMessage *const response, const mDNSu8 *end,
const mDNSInterfaceID InterfaceID, CacheRecord **NSEC3Records)
{
- const mDNSu8 *ptr = response->data;
+ const mDNSu8 *ptr;
CacheRecord *rr;
int i;
@@ -8709,24 +8708,6 @@ mDNSlocal void mDNSCoreResetRecord(mDNS *const m)
}
}
-#define DEVICE_INFO_RECORD_LABELS 4
-
-// Determine if the record is an instance of _device-info._tcp.local.
-mDNSlocal mDNSBool IsDeviceInfoRecord(const domainname *d)
-{
- const domainname *afterInstance;
-
- if (CountLabels(d) != DEVICE_INFO_RECORD_LABELS)
- return mDNSfalse;
-
- // skip the instance name
- afterInstance = SkipLeadingLabels(d, 1);
- if (SameDomainName(afterInstance, &LocalDeviceInfoName))
- return mDNStrue;
-
- return mDNSfalse;
-}
-
// Note: mDNSCoreReceiveResponse calls mDNS_Deregister_internal which can call a user callback, which may change
// the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
@@ -8739,9 +8720,8 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
const mDNSInterfaceID InterfaceID)
{
int i;
- mDNSBool myself;
mDNSBool ResponseMCast = dstaddr && mDNSAddrIsDNSMulticast(dstaddr);
- mDNSBool ResponseSrcLocal = !srcaddr || mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr, &myself);
+ mDNSBool ResponseSrcLocal = !srcaddr || mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr);
DNSQuestion *llqMatch = mDNSNULL;
DNSQuestion *unicastQuestion = mDNSNULL;
uDNS_LLQType LLQType = uDNS_recvLLQResponse(m, response, end, srcaddr, srcport, &llqMatch);
@@ -8759,12 +8739,11 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
mDNSu8 rcode = '\0';
mDNSBool rrsigsCreated = mDNSfalse;
mDNSBool DNSSECQuestion = mDNSfalse;
- mDNSBool recordAccepted = mDNSfalse;
NetworkInterfaceInfo *llintf = FirstIPv4LLInterfaceForID(m, InterfaceID);
// All records in a DNS response packet are treated as equally valid statements of truth. If we want
// to guard against spoof responses, then the only credible protection against that is cryptographic
- // security, e.g. DNSSEC., not worring about which section in the spoof packet contained the record
+ // security, e.g. DNSSEC., not worrying about which section in the spoof packet contained the record.
int firstauthority = response->h.numAnswers;
int firstadditional = firstauthority + response->h.numAuthorities;
int totalrecords = firstadditional + response->h.numAdditionals;
@@ -9000,64 +8979,69 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
// Even though it is AcceptableResponse, we still need a DNSServer pointer for the resource records that
// we create.
- if (!mDNSOpaque16IsZero(response->h.id))
- {
- DNSQuestion *q = ExpectingUnicastResponseForRecord(m, srcaddr, ResponseSrcLocal, dstport, response->h.id, &m->rec.r, !dstaddr);
-
- // Initialize the DNS server on the resource record which will now filter what questions we answer with
- // this record.
- //
- // We could potentially lookup the DNS server based on the source address, but that may not work always
- // and that's why ExpectingUnicastResponseForRecord does not try to verify whether the response came
- // from the DNS server that queried. We follow the same logic here. If we can find a matching quetion based
- // on the "id" and "source port", then this response answers the question and assume the response
- // came from the same DNS server that we sent the query to.
-
- if (q != mDNSNULL)
- {
- AcceptableResponse = mDNStrue;
- if (!InterfaceID)
- {
- debugf("mDNSCoreReceiveResponse: InterfaceID %p %##s (%s)", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
- m->rec.r.resrec.rDNSServer = uDNSServer = q->qDNSServer;
- }
- else
- LogInfo("mDNSCoreReceiveResponse: InterfaceID %p %##s (%s)", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
- }
- else
- {
- // If we can't find a matching question, we need to see whether we have seen records earlier that matched
- // the question. The code below does that. So, make this record unacceptable for now
- if (!InterfaceID)
- {
- debugf("mDNSCoreReceiveResponse: Can't find question for record name %##s", m->rec.r.resrec.name->c);
- AcceptableResponse = mDNSfalse;
- }
- }
- }
- else if (ExpectingMulticastResponseForRecord(m, &m->rec.r, srcaddr, recordAccepted, &McastNSEC3Records))
- {
- recordAccepted = mDNStrue;
- AcceptableResponse = mDNStrue;
- LogInfo("mDNSCoreReceiveResponse: Accepting record in response to QU question %s, InterfaceID %p", CRDisplayString(m, &m->rec.r),
- InterfaceID);
- }
- else if (IsDeviceInfoRecord(m->rec.r.resrec.name))
- {
- recordAccepted = mDNStrue;
- AcceptableResponse = mDNStrue;
- LogInfo("mDNSCoreReceiveResponse: Accepting _device-info record %s, InterfaceID %p",
- CRDisplayString(m, &m->rec.r), InterfaceID);
- }
+ DNSQuestion *q = ExpectingUnicastResponseForRecord(m, srcaddr, ResponseSrcLocal, dstport, response->h.id, &m->rec.r, !dstaddr);
+
+ // Initialize the DNS server on the resource record which will now filter what questions we answer with
+ // this record.
+ //
+ // We could potentially lookup the DNS server based on the source address, but that may not work always
+ // and that's why ExpectingUnicastResponseForRecord does not try to verify whether the response came
+ // from the DNS server that queried. We follow the same logic here. If we can find a matching quetion based
+ // on the "id" and "source port", then this response answers the question and assume the response
+ // came from the same DNS server that we sent the query to.
+
+ if (q != mDNSNULL)
+ {
+ AcceptableResponse = mDNStrue;
+ if (!InterfaceID)
+ {
+ debugf("mDNSCoreReceiveResponse: InterfaceID %p %##s (%s)", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
+ m->rec.r.resrec.rDNSServer = uDNSServer = q->qDNSServer;
+ }
+ else
+ LogInfo("mDNSCoreReceiveResponse: InterfaceID %p %##s (%s)", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
+ }
+ else
+ {
+ // If we can't find a matching question, we need to see whether we have seen records earlier that matched
+ // the question. The code below does that. So, make this record unacceptable for now
+ if (!InterfaceID)
+ {
+ debugf("mDNSCoreReceiveResponse: Can't find question for record name %##s", m->rec.r.resrec.name->c);
+ AcceptableResponse = mDNSfalse;
+ }
+ }
}
}
else if (llintf && llintf->IgnoreIPv4LL && m->rec.r.resrec.rrtype == kDNSType_A)
{
- CacheRecord *const rr = &m->rec.r;
- RDataBody2 *const rdb = (RDataBody2 *)rr->smallrdatastorage.data;
-
- // If we are supposed to ignore link-local addresses on this interface, drop
- // all "A" records that have link-local address in them.
+ // There are some routers (rare, thankfully) that generate bogus ARP responses for
+ // any IPv4 address they don’t recognize, including RFC 3927 IPv4 link-local addresses.
+ // To work with these broken routers, client devices need to blacklist these broken
+ // routers and ignore their bogus ARP responses. Some devices implement a technique
+ // such as the one described in US Patent 7436783, which lets clients detect and
+ // ignore these broken routers: <https://www.google.com/patents/US7436783>
+
+ // OS X and iOS do not implement this defensive mechanism, instead taking a simpler
+ // approach of just detecting these broken routers and completely disabling IPv4
+ // link-local communication on interfaces where a broken router is detected.
+ // OS X and iOS set the IFEF_ARPLL interface flag on interfaces
+ // that are deemed “safe” for IPv4 link-local communication;
+ // the flag is cleared on interfaces where a broken router is detected.
+
+ // OS X and iOS will not even try to communicate with an IPv4
+ // link-local destination on an interface without the IFEF_ARPLL flag set.
+ // This can cause some badly written applications to freeze for a long time if they
+ // attempt to connect to an IPv4 link-local destination address and then wait for
+ // that connection attempt to time out before trying other candidate addresses.
+
+ // To mask this client bug, we suppress acceptance of IPv4 link-local address
+ // records on interfaces where we know the OS will be unwilling even to attempt
+ // communication with those IPv4 link-local destination addresses.
+ // <rdar://problem/9400639> kSuppress IPv4LL answers on interfaces without IFEF_ARPLL
+
+ const CacheRecord *const rr = &m->rec.r;
+ const RDataBody2 *const rdb = (RDataBody2 *)rr->smallrdatastorage.data;
if (mDNSv4AddressIsLinkLocal(&rdb->ipv4))
{
LogInfo("mDNSResponder: Dropping LinkLocal packet %s", CRDisplayString(m, &m->rec.r));
@@ -9116,7 +9100,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
if (rr->ProbeCount > DefaultProbeCountForTypeUnique)
LogInfo("mDNSCoreReceiveResponse: Already reset to Probing: %s", ARDisplayString(m, rr));
else if (rr->ProbeCount == DefaultProbeCountForTypeUnique)
- LogMsg("mDNSCoreReceiveResponse: Ignoring response received before we even began probing: %s", ARDisplayString(m, rr));
+ LogInfo("mDNSCoreReceiveResponse: Ignoring response received before we even began probing: %s", ARDisplayString(m, rr));
else
{
LogMsg("mDNSCoreReceiveResponse: Received from %#a:%d %s", srcaddr, mDNSVal16(srcport), CRDisplayString(m, &m->rec.r));
@@ -9202,27 +9186,6 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
rr = mDNSCoreReceiveCacheCheck(m, response, LLQType, slot, cg, unicastQuestion, &cfp, &NSECCachePtr, InterfaceID);
}
- // If mDNSOppCaching is set (which affects only multicast), enable opportunistic caching in which case we cache
- // everything that was received over multicast. Otherwise, we are selective about the caching.
- //
- // Cache everything that is from ourselves (that's how we answer any questions looking for them). Otherwise call
- // ExpectingMulticastResponseForRecord which decides whether to cache this record or not.
- //
- if (!m->mDNSOppCaching && !rr && !myself && mDNSOpaque16IsZero(response->h.id))
- {
- if (!ExpectingMulticastResponseForRecord(m, &m->rec.r, srcaddr, recordAccepted, &McastNSEC3Records))
- {
- //LogMsg("mDNSCoreReceiveResponse: discarding %s", CRDisplayString(m, &m->rec.r));
- mDNSCoreResetRecord(m);
- continue;
- }
- else
- {
- recordAccepted = mDNStrue;
- }
- }
-
-
// If packet resource record not in our cache, add it now
// (unless it is just a deletion of a record we never had, in which case we don't care)
if (!rr && m->rec.r.resrec.rroriginalttl > 0)
@@ -9360,15 +9323,22 @@ exit:
// goodbye announcement with the cache flush bit set (or a case-change on record rdata,
// which we treat as a goodbye followed by an addition) and in that case it would be
// inappropriate to synchronize all the other records to a TTL of 0 (or 1).
+
// We suppress the message for the specific case of correcting from 240 to 60 for type TXT,
// because certain early Bonjour devices are known to have this specific mismatch, and
// there's no point filling syslog with messages about something we already know about.
// We also don't log this for uDNS responses, since a caching name server is obliged
// to give us an aged TTL to correct for how long it has held the record,
// so our received TTLs are expected to vary in that case
+
+ // We also suppress log message in the case of SRV records that are recieved
+ // with a TTL of 4500 that are already cached with a TTL of 120 seconds, since
+ // this behavior was observed for a number of discoveryd based AppleTV's in iOS 8
+ // GM builds.
if (r2->resrec.rroriginalttl != r1->resrec.rroriginalttl && r1->resrec.rroriginalttl > 1)
{
if (!(r2->resrec.rroriginalttl == 240 && r1->resrec.rroriginalttl == 60 && r2->resrec.rrtype == kDNSType_TXT) &&
+ !(r2->resrec.rroriginalttl == 120 && r1->resrec.rroriginalttl == 4500 && r2->resrec.rrtype == kDNSType_SRV) &&
mDNSOpaque16IsZero(response->h.id))
LogInfo("Correcting TTL from %4d to %4d for %s",
r2->resrec.rroriginalttl, r1->resrec.rroriginalttl, CRDisplayString(m, r2));
@@ -9555,7 +9525,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++)
{
@@ -9567,7 +9537,12 @@ mDNSlocal mDNSu8 *GetValueForMACAddr(mDNSu8 *ptr, mDNSu8 *limit, mDNSEthAddr *et
}
else if (*ptr == ':')
{
- eth->b[colons] = val;
+ if (colons >=5 || val > 255)
+ {
+ LogMsg("GetValueForMACAddr: Address malformed colons %d val %d", colons, val);
+ return mDNSNULL;
+ }
+ eth->b[colons] = (mDNSs8)val;
colons++;
val = 0;
}
@@ -9577,7 +9552,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;
}
@@ -9698,6 +9673,11 @@ mDNSlocal mDNSu8 *GetValueForIPv4Addr(mDNSu8 *ptr, mDNSu8 *limit, mDNSv4Addr *v4
val = val * 10 + *ptr - '0';
else if (*ptr == '.')
{
+ if (val > 255 || dots >= 3)
+ {
+ LogMsg("GetValueForIPv4Addr: something wrong ptr(%p) %c, limit %p, dots %d", ptr, *ptr, limit, dots);
+ return mDNSNULL;
+ }
v4->b[dots++] = val;
val = 0;
}
@@ -9740,6 +9720,37 @@ mDNSlocal mDNSu8 *GetValueForKeepalive(mDNSu8 *ptr, mDNSu8 *limit, mDNSu32 *valu
return ptr;
}
+mDNSexport mDNSBool mDNSValidKeepAliveRecord(AuthRecord *rr)
+{
+ mDNSAddr laddr, raddr;
+ mDNSEthAddr eth;
+ mDNSIPPort lport, rport;
+ mDNSu32 timeout, seq, ack;
+ mDNSu16 win;
+
+ if (!mDNS_KeepaliveRecord(&rr->resrec))
+ {
+ return mDNSfalse;
+ }
+
+ timeout = seq = ack = 0;
+ win = 0;
+ laddr = raddr = zeroAddr;
+ lport = rport = zeroIPPort;
+
+ mDNS_ExtractKeepaliveInfo(rr, &timeout, &laddr, &raddr, &eth, &seq, &ack, &lport, &rport, &win);
+
+ if (mDNSAddressIsZero(&laddr) || mDNSIPPortIsZero(lport) ||
+ mDNSAddressIsZero(&raddr) || mDNSIPPortIsZero(rport) ||
+ mDNSEthAddressIsZero(eth))
+ {
+ return mDNSfalse;
+ }
+
+ return mDNStrue;
+}
+
+
mDNSlocal void mDNS_ExtractKeepaliveInfo(AuthRecord *ar, mDNSu32 *timeout, mDNSAddr *laddr, mDNSAddr *raddr, mDNSEthAddr *eth, mDNSu32 *seq,
mDNSu32 *ack, mDNSIPPort *lport, mDNSIPPort *rport, mDNSu16 *win)
{
@@ -9916,16 +9927,18 @@ mDNSlocal void mDNS_SendKeepalives(mDNS *const m)
mDNSlocal void mDNS_SendKeepaliveACK(mDNS *const m, AuthRecord *ar)
{
- if (ar != mDNSNULL)
- {
- LogInfo("mDNS_SendKeepalivesACK: AuthRecord is NULL");
- return;
- }
- mDNSu32 timeout, seq, ack;
+ mDNSu32 timeout, seq, ack, seqInc;
mDNSu16 win;
mDNSAddr laddr, raddr;
mDNSEthAddr eth;
mDNSIPPort lport, rport;
+ mDNSu8 *ptr;
+
+ if (ar == mDNSNULL)
+ {
+ LogInfo("mDNS_SendKeepalivesACK: AuthRecord is NULL");
+ return;
+ }
timeout = seq = ack = 0;
win = 0;
@@ -9940,6 +9953,17 @@ mDNSlocal void mDNS_SendKeepaliveACK(mDNS *const m, AuthRecord *ar)
LogInfo("mDNS_SendKeepaliveACK: not a valid record %s for keepalive", ARDisplayString(m, ar));
return;
}
+
+ // To send a keepalive ACK, we need to add one to the sequence number from the keepalive
+ // record, which is the TCP connection's "next" sequence number minus one. Otherwise, the
+ // keepalive ACK also ends up being a keepalive probe. Also, seq is in network byte order, so
+ // it's converted to host byte order before incrementing it by one.
+ ptr = (mDNSu8 *)&seq;
+ seqInc = (mDNSu32)((ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]) + 1;
+ ptr[0] = (mDNSu8)((seqInc >> 24) & 0xFF);
+ ptr[1] = (mDNSu8)((seqInc >> 16) & 0xFF);
+ ptr[2] = (mDNSu8)((seqInc >> 8) & 0xFF);
+ ptr[3] = (mDNSu8)((seqInc ) & 0xFF);
LogMsg("mDNS_SendKeepaliveACK: laddr %#a raddr %#a lport %d rport %d", &laddr, &raddr, mDNSVal16(lport), mDNSVal16(rport));
mDNSPlatformSendKeepalive(&laddr, &raddr, &lport, &rport, seq, ack, win);
}
@@ -10106,6 +10130,8 @@ mDNSlocal void mDNSCoreReceiveUpdateR(mDNS *const m, const DNSMessage *const msg
{
mDNSu32 updatelease = 60 * 60; // If SPS fails to indicate lease time, assume one hour
const mDNSu8 *ptr = LocateOptRR(msg, end, DNSOpt_LeaseData_Space);
+ mDNSAddr spsaddr;
+ char *ifname;
if (ptr)
{
ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
@@ -10155,8 +10181,7 @@ mDNSlocal void mDNSCoreReceiveUpdateR(mDNS *const m, const DNSMessage *const msg
}
// Update the dynamic store with the IP Address and MAC address of the sleep proxy
- char *ifname = InterfaceNameForID(m, InterfaceID);
- mDNSAddr spsaddr;
+ ifname = InterfaceNameForID(m, InterfaceID);
mDNSPlatformMemCopy(&spsaddr, srcaddr, sizeof (mDNSAddr));
mDNSPlatformStoreSPSMACAddr(&spsaddr, ifname);
}
@@ -10169,12 +10194,7 @@ mDNSexport void MakeNegativeCacheRecord(mDNS *const m, CacheRecord *const cr,
const domainname *const name, const mDNSu32 namehash, const mDNSu16 rrtype, const mDNSu16 rrclass, mDNSu32 ttl_seconds, mDNSInterfaceID InterfaceID, DNSServer *dnsserver)
{
if (cr == &m->rec.r && m->rec.r.resrec.RecordType)
- {
- LogMsg("MakeNegativeCacheRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
-#if ForceAlerts
- *(long*)0 = 0;
-#endif
- }
+ LogFatalError("MakeNegativeCacheRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
// Create empty resource record
cr->resrec.RecordType = kDNSRecordTypePacketNegative;
@@ -10282,7 +10302,7 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, void *const pkt, const mDNSu8 *co
// Track the number of multicast packets received from a source outside our subnet.
// Check the destination address to avoid accounting for spurious packets that
// comes in with message id zero.
- if (!mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr, mDNSNULL) &&
+ if (!mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr) &&
mDNSAddressIsAllDNSLinkGroup(dstaddr))
{
m->RemoteSubnet++;
@@ -10489,8 +10509,8 @@ mDNSexport McastResolver *mDNS_AddMcastResolver(mDNS *const m, const domainname
{
if ((*p)->interface == interface && SameDomainName(&(*p)->domain, d))
{
- if (!((*p)->flags & DNSServer_FlagDelete)) LogMsg("Note: Mcast Resolver domain %##s (%p) registered more than once", d->c, interface);
- (*p)->flags &= ~DNSServer_FlagDelete;
+ if (!((*p)->flags & McastResolver_FlagDelete)) LogMsg("Note: Mcast Resolver domain %##s (%p) registered more than once", d->c, interface);
+ (*p)->flags &= ~McastResolver_FlagDelete;
tmp = *p;
*p = tmp->next;
tmp->next = mDNSNULL;
@@ -10508,7 +10528,7 @@ mDNSexport McastResolver *mDNS_AddMcastResolver(mDNS *const m, const domainname
else
{
(*p)->interface = interface;
- (*p)->flags = DNSServer_FlagNew;
+ (*p)->flags = McastResolver_FlagNew;
(*p)->timeout = timeout;
AssignDomainName(&(*p)->domain, d);
(*p)->next = mDNSNULL;
@@ -10714,9 +10734,10 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
//
// Note: DNS configuration change will help pick the new dns servers but currently it does not affect the timeout
- if (curr->scoped && curr->interface == mDNSInterface_Any)
+ // Skip DNSServers that are InterfaceID Scoped but have no valid interfaceid set OR DNSServers that are ServiceID Scoped but have no valid serviceid set
+ if ((curr->scoped == kScopeInterfaceID && curr->interface == mDNSInterface_Any) || (curr->scoped == kScopeServiceID && curr->serviceID <= 0))
{
- debugf("SetValidDNSServers: Scoped DNS server %#a (Domain %##s) with Interface Any", &curr->addr, curr->domain.c);
+ LogInfo("SetValidDNSServers: ScopeType[%d] Skipping DNS server %#a (Domain %##s) Interface:[%p] Serviceid:[%d]", curr->scoped, &curr->addr, curr->domain.c, curr->interface, curr->serviceID);
continue;
}
@@ -11367,6 +11388,9 @@ mDNSlocal void InitDNSConfig(mDNS *const m, DNSQuestion *const question)
question->triedAllServersOnce = 0;
question->noServerResponse = 0;
question->StopTime = 0;
+#if TARGET_OS_EMBEDDED
+ mDNSPlatformMemZero(&question->metrics, sizeof(question->metrics));
+#endif
// Need not initialize the DNS Configuration for Local Only OR P2P Questions
if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P)
@@ -11415,6 +11439,7 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
{
mDNSBool purge;
int i;
+ mDNSBool isCellBlocked = mDNSfalse;
// Note: In the case where we already have the answer to this question in our cache, that may be all the client
// wanted, and they may immediately cancel their question. In this case, sending an actual query on the wire would
@@ -11463,14 +11488,14 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
question->FlappingInterface1 = mDNSNULL;
question->FlappingInterface2 = mDNSNULL;
- // if kDNSServiceFlagsServiceIndex flag is SET by the client, then do NOT call mDNSPlatformGetServiceID()
+ // if kDNSServiceFlagsServiceIndex flag is SET by the client, then do NOT call mDNSPlatformGetDNSRoutePolicy()
// since we would already have the question->ServiceID in that case.
if (!(question->flags & kDNSServiceFlagsServiceIndex))
- question->ServiceID = mDNSPlatformGetServiceID(m, question);
+ mDNSPlatformGetDNSRoutePolicy(m, question, &isCellBlocked);
else
- LogInfo("InitCommonState: Query for %##s (%s), PID[%d], ServiceID %d is already set by client", question->qname.c,
- DNSTypeName(question->qtype), question->pid, question->ServiceID);
-
+ LogInfo("InitCommonState: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] is already set by client", question->qname.c,
+ DNSTypeName(question->qtype), question->pid, question->euid, question->ServiceID);
+
InitDNSConfig(m, question);
question->AuthInfo = GetAuthInfoForQuestion(m, question);
@@ -11480,10 +11505,10 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
// If ServiceID is 0 or the policy disallows making DNS requests,
// set DisallowPID
- question->DisallowPID = (question->ServiceID == 0 || (mDNSPlatformAllowPID(m, question) == 0));
+ question->DisallowPID = (question->ServiceID == 0 || (isCellBlocked && question->qDNSServer && question->qDNSServer->cellIntf));
if (question->DisallowPID)
LogInfo("InitCommonState: Query suppressed for %##s (%s), PID %d/ServiceID %d not allowed", question->qname.c,
- DNSTypeName(question->qtype), question->pid, question->ServiceID);
+ DNSTypeName(question->qtype), question->pid, question->ServiceID);
question->NextInDQList = mDNSNULL;
question->SendQNow = mDNSNULL;
@@ -11602,7 +11627,7 @@ mDNSlocal void InitDNSSECProxyState(mDNS *const m, DNSQuestion *const question)
{
if (question->qDNSServer->cellIntf)
{
- LogInfo("InitDNSSECProxyState: Turning off validation for %##s (%s); going over cell", question->qname.c, DNSTypeName(question->qtype));
+ debugf("InitDNSSECProxyState: Turning off validation for %##s (%s); going over cell", question->qname.c, DNSTypeName(question->qtype));
question->ValidationRequired = mDNSfalse;
}
if (DNSSECOptionalQuestion(question) && !(question->qDNSServer->req_DO))
@@ -11739,6 +11764,13 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
}
else
{
+#if TARGET_OS_WATCH
+ m->NumAllInterfaceQuestions++;
+ LogInfo("mDNS_StartQuery_internal: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %##s (%s)",
+ m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, question->qname.c, DNSTypeName(question->qtype));
+ if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
+ m->NetworkChanged = m->timenow;
+#endif
if (purge)
{
LogInfo("mDNS_StartQuery_internal: Purging for %##s", question->qname.c);
@@ -11783,14 +11815,35 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
#if !ForceAlerts
if (question->ThisQInterval >= 0) // Only log error message if the query was supposed to be active
#endif
- LogMsg("mDNS_StopQuery_internal: Question %##s (%s) not found in active list",
- question->qname.c, DNSTypeName(question->qtype));
-#if ForceAlerts
- *(long*)0 = 0;
-#endif
+ LogFatalError("mDNS_StopQuery_internal: Question %##s (%s) not found in active list", question->qname.c, DNSTypeName(question->qtype));
return(mStatus_BadReferenceErr);
}
+#if TARGET_OS_WATCH
+ if (question->InterfaceID != mDNSInterface_LocalOnly && question->InterfaceID != mDNSInterface_P2P && mDNSOpaque16IsZero(question->TargetQID))
+ {
+ if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
+ m->NetworkChanged = m->timenow;
+ m->NumAllInterfaceQuestions--;
+ LogInfo("mDNS_StopQuery_internal: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %##s (%s)",
+ m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, question->qname.c, DNSTypeName(question->qtype));
+ }
+#endif
+
+#if TARGET_OS_EMBEDDED
+ if (Question_uDNS(question) && !question->metrics.answered)
+ {
+ uDNSMetrics * metrics;
+ const domainname * queryName;
+ mDNSBool isForCellular;
+
+ metrics = &question->metrics;
+ queryName = metrics->originalQName ? metrics->originalQName : &question->qname;
+ isForCellular = (question->qDNSServer && question->qDNSServer->cellIntf);
+
+ MetricsUpdateUDNSStats(queryName, mDNSfalse, metrics->querySendCount, 0, isForCellular);
+ }
+#endif
// Take care to cut question from list *before* calling UpdateQuestionDuplicates
UpdateQuestionDuplicates(m, question);
// But don't trash ThisQInterval until afterwards.
@@ -11913,6 +11966,13 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
FreeAnonInfo(question->AnonInfo);
question->AnonInfo = mDNSNULL;
}
+#if TARGET_OS_EMBEDDED
+ if (question->metrics.originalQName)
+ {
+ mDNSPlatformMemFree(question->metrics.originalQName);
+ question->metrics.originalQName = mDNSNULL;
+ }
+#endif
return(mStatus_NoError);
}
@@ -12365,6 +12425,7 @@ mDNSexport mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, m
question->qnameOrig = mDNSNULL;
question->AnonInfo = mDNSNULL;
question->pid = mDNSPlatformGetPID();
+ question->euid = 0;
question->QuestionCallback = Callback;
question->QuestionContext = Context;
if (DomainType > mDNS_DomainTypeMax) return(mStatus_BadParamErr);
@@ -12481,26 +12542,20 @@ mDNSlocal void AdvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
{
char buffer[MAX_REVERSE_MAPPING_NAME];
NetworkInterfaceInfo *primary;
+ mDNSu8 recordType;
- if (!set->McastTxRx)
- {
- LogInfo("AdvertiseInterface: Returning, not multicast capable %s", set->ifname);
- return;
- }
-#if TARGET_OS_EMBEDDED
- if (!m->AutoTargetServices)
+ if (m->AutoTargetServices == 0)
{
LogInfo("AdvertiseInterface: Returning due to AutoTargetServices zero for %s", set->ifname);
return;
}
-#endif
primary = FindFirstAdvertisedInterface(m);
if (!primary) primary = set; // If no existing advertised interface, this new NetworkInterfaceInfo becomes our new primary
// If interface is marked as a direct link, we can assume the address record is unique
// and does not need to go through the probe phase of the probe/announce packet sequence.
- mDNSu8 recordType = (set->DirectLink ? kDNSRecordTypeKnownUnique : kDNSRecordTypeUnique);
+ recordType = (set->DirectLink ? kDNSRecordTypeKnownUnique : kDNSRecordTypeUnique);
if (set->DirectLink)
LogInfo("AdvertiseInterface: Marking address record as kDNSRecordTypeKnownUnique for %s", set->ifname);
@@ -12575,22 +12630,19 @@ mDNSlocal void AdvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
mDNSlocal void DeadvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
{
- NetworkInterfaceInfo *intf;
-
- // If we still have address records referring to this one, update them
- NetworkInterfaceInfo *primary = FindFirstAdvertisedInterface(m);
- AuthRecord *A = primary ? &primary->RR_A : mDNSNULL;
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->RR_A.RRSet == &set->RR_A)
- intf->RR_A.RRSet = A;
+ if (m->AutoTargetServices == 0)
+ {
+ LogInfo("DeadvertiseInterface: Returning due to AutoTargetServices zero for %s", set->ifname);
+ return;
+ }
// Unregister these records.
// When doing the mDNS_Exit processing, we first call DeadvertiseInterface for each interface, so by the time the platform
// support layer gets to call mDNS_DeregisterInterface, the address and PTR records have already been deregistered for it.
// Also, in the event of a name conflict, one or more of our records will have been forcibly deregistered.
// To avoid unnecessary and misleading warning messages, we check the RecordType before calling mDNS_Deregister_internal().
- if (set->RR_A.resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_A, mDNS_Dereg_normal);
- if (set->RR_PTR.resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_PTR, mDNS_Dereg_normal);
+ if (set->RR_A .resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_A, mDNS_Dereg_normal);
+ if (set->RR_PTR .resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_PTR, mDNS_Dereg_normal);
if (set->RR_HINFO.resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_HINFO, mDNS_Dereg_normal);
#if APPLE_OSX_mDNSResponder
@@ -12614,7 +12666,6 @@ mDNSlocal void AdvertiseAllInterfaceRecords(mDNS *const m)
mDNSlocal void DeadvertiseAllInterfaceRecords(mDNS *const m)
{
-#if TARGET_OS_EMBEDDED
NetworkInterfaceInfo *intf;
for (intf = m->HostInterfaces; intf; intf = intf->next)
{
@@ -12624,15 +12675,11 @@ mDNSlocal void DeadvertiseAllInterfaceRecords(mDNS *const m)
DeadvertiseInterface(m, intf);
}
}
-#else
- (void) m; //unused
-#endif
}
mDNSexport void mDNS_SetFQDN(mDNS *const m)
{
domainname newmname;
- NetworkInterfaceInfo *intf;
AuthRecord *rr;
newmname.c[0] = 0;
@@ -12645,14 +12692,8 @@ mDNSexport void mDNS_SetFQDN(mDNS *const m)
else
{
AssignDomainName(&m->MulticastHostname, &newmname);
-
- // 1. Stop advertising our address records on all interfaces
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->Advertise) DeadvertiseInterface(m, intf);
-
- // 2. Start advertising our address records using the new name
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->Advertise) AdvertiseInterface(m, intf);
+ DeadvertiseAllInterfaceRecords(m);
+ AdvertiseAllInterfaceRecords(m);
}
// 3. Make sure that any AutoTarget SRV records (and the like) get updated
@@ -12971,6 +13012,9 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
{
NetworkInterfaceInfo **p = &m->HostInterfaces;
mDNSBool revalidate = mDNSfalse;
+ NetworkInterfaceInfo *primary;
+ NetworkInterfaceInfo *intf;
+ AuthRecord *A;
mDNS_Lock(m);
@@ -12987,14 +13031,13 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
if (!set->InterfaceActive)
{
// If this interface not the active member of its set, update the v4/v6Available flags for the active member
- NetworkInterfaceInfo *intf;
for (intf = m->HostInterfaces; intf; intf = intf->next)
if (intf->InterfaceActive && intf->InterfaceID == set->InterfaceID)
UpdateInterfaceProtocols(m, intf);
}
else
{
- NetworkInterfaceInfo *intf = FirstInterfaceForID(m, set->InterfaceID);
+ intf = FirstInterfaceForID(m, set->InterfaceID);
if (intf)
{
LogInfo("mDNS_DeregisterInterface: Another representative of InterfaceID %d %s (%#a) exists;"
@@ -13027,7 +13070,7 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
if (set->McastTxRx && flapping)
{
- LogMsg("DeregisterInterface: Frequent transitions for interface %s (%#a)", set->ifname, &set->ip);
+ LogMsg("mDNS_DeregisterInterface: Frequent transitions for interface %s (%#a)", set->ifname, &set->ip);
m->mDNSStats.InterfaceDownFlap++;
}
@@ -13068,6 +13111,15 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
}
}
+ // If we still have address records referring to this one, update them.
+ // This is safe, because this NetworkInterfaceInfo has already been unlinked from the list,
+ // so the call to FindFirstAdvertisedInterface() won’t accidentally find it.
+ primary = FindFirstAdvertisedInterface(m);
+ A = primary ? &primary->RR_A : mDNSNULL;
+ for (intf = m->HostInterfaces; intf; intf = intf->next)
+ if (intf->RR_A.RRSet == &set->RR_A)
+ intf->RR_A.RRSet = A;
+
// If we were advertising on this interface, deregister those address and reverse-lookup records now
if (set->Advertise) DeadvertiseInterface(m, set);
@@ -13390,8 +13442,6 @@ mDNSexport mStatus mDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr,
e = &sr->Extras;
while (*e) e = &(*e)->next;
- if (ttl == 0) ttl = kStandardTTL;
-
extra->r.DependentOn = &sr->RR_SRV;
debugf("mDNS_AddRecordToService adding record to %##s %s %d",
@@ -14045,11 +14095,13 @@ mDNSexport void mDNSCoreReceiveRawPacket(mDNS *const m, const mDNSu8 *const p, c
else if (end >= p+34 && mDNSSameOpaque16(eth->ethertype, Ethertype_IPv4) && (pkt->v4.flagsfrags.b[0] & 0x1F) == 0 && pkt->v4.flagsfrags.b[1] == 0)
{
const mDNSu8 *const trans = p + 14 + (pkt->v4.vlen & 0xF) * 4;
+ const mDNSu8 * transEnd = p + 14 + mDNSVal16(pkt->v4.totlen);
+ if (transEnd > end) transEnd = end;
debugf("Got IPv4 %02X from %.4a to %.4a", pkt->v4.protocol, &pkt->v4.src, &pkt->v4.dst);
src.type = mDNSAddrType_IPv4; src.ip.v4 = pkt->v4.src;
dst.type = mDNSAddrType_IPv4; dst.ip.v4 = pkt->v4.dst;
- if (end >= trans + RequiredCapLen(pkt->v4.protocol))
- mDNSCoreReceiveRawTransportPacket(m, &eth->src, &src, &dst, pkt->v4.protocol, p, (TransportLayerPacket*)trans, end, InterfaceID, 0);
+ if (transEnd >= trans + RequiredCapLen(pkt->v4.protocol))
+ mDNSCoreReceiveRawTransportPacket(m, &eth->src, &src, &dst, pkt->v4.protocol, p, (TransportLayerPacket*)trans, transEnd, InterfaceID, 0);
}
// Is IPv6? Length must be at least 14 + 28 = 42 bytes
else if (end >= p+54 && mDNSSameOpaque16(eth->ethertype, Ethertype_IPv6))
@@ -14180,6 +14232,7 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
if (!rrcachestorage) rrcachesize = 0;
m->p = p;
+ m->NetworkChanged = 0;
m->CanReceiveUnicastOn5353 = mDNSfalse; // Assume we can't receive unicasts on 5353, unless platform layer tells us otherwise
m->AdvertiseLocalAddresses = AdvertiseLocalAddresses;
m->DivertMulticastAdvertisements = mDNSfalse;
@@ -14302,13 +14355,20 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
m->WABBrowseQueriesCount = 0;
m->WABLBrowseQueriesCount = 0;
m->WABRegQueriesCount = 0;
-#if !TARGET_OS_EMBEDDED
- m->mDNSOppCaching = mDNStrue;
+#if TARGET_OS_EMBEDDED || TARGET_OS_WATCH
+ m->AutoTargetServices = 0;
#else
- m->mDNSOppCaching = mDNSfalse;
+ m->AutoTargetServices = 1;
+#endif
+#if TARGET_OS_WATCH
+ m->NumAllInterfaceRecords = 0;
+ m->NumAllInterfaceQuestions = 0;
+#else
+ // Initialize to 1 for these targets to prevent not joining multicast group for interfaces when
+ // both of these values are zero.
+ m->NumAllInterfaceRecords = 1;
+ m->NumAllInterfaceQuestions = 1;
#endif
- m->AutoTargetServices = 0;
-
// NAT traversal fields
m->LLQNAT.clientCallback = mDNSNULL;
m->LLQNAT.clientContext = mDNSNULL;
@@ -14545,6 +14605,10 @@ mDNSlocal void SetConfigState(mDNS *const m, mDNSBool delete)
ptr->penaltyTime = 0;
NumUnicastDNSServers--;
ptr->flags |= DNSServer_FlagDelete;
+#if APPLE_OSX_mDNSResponder
+ if (ptr->flags & DNSServer_FlagUnreachable)
+ NumUnreachableDNSServers--;
+#endif
}
// We handle the mcast resolvers here itself as mDNSPlatformSetDNSConfig looks at
// mcast resolvers. Today we get both mcast and ucast configuration using the same
@@ -14559,6 +14623,10 @@ mDNSlocal void SetConfigState(mDNS *const m, mDNSBool delete)
ptr->penaltyTime = 0;
NumUnicastDNSServers++;
ptr->flags &= ~DNSServer_FlagDelete;
+#if APPLE_OSX_mDNSResponder
+ if (ptr->flags & DNSServer_FlagUnreachable)
+ NumUnreachableDNSServers++;
+#endif
}
for (mr = m->McastResolvers; mr; mr = mr->next)
mr->flags &= ~McastResolver_FlagDelete;
@@ -14607,7 +14675,7 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
// affecting them as they never change.
while (*mres)
{
- if (((*mres)->flags & DNSServer_FlagDelete) != 0)
+ if (((*mres)->flags & McastResolver_FlagDelete) != 0)
{
mr = *mres;
*mres = (*mres)->next;
@@ -14668,6 +14736,7 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
tport = t->port;
else
tport = zeroIPPort;
+
if (s)
sport = s->port;
else
@@ -14724,8 +14793,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; }
}
@@ -14943,7 +15013,6 @@ mDNSlocal void DeregLoop(mDNS *const m, AuthRecord *const start)
mDNSexport void mDNS_StartExit(mDNS *const m)
{
- NetworkInterfaceInfo *intf;
AuthRecord *rr;
mDNS_Lock(m);
@@ -14983,9 +15052,7 @@ mDNSexport void mDNS_StartExit(mDNS *const m)
}
#endif
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->Advertise)
- DeadvertiseInterface(m, intf);
+ DeadvertiseAllInterfaceRecords(m);
// Shut down all our active NAT Traversals
while (m->NATTraversals)
@@ -15045,6 +15112,7 @@ mDNSexport void mDNS_StartExit(mDNS *const m)
mDNSexport void mDNS_FinalExit(mDNS *const m)
{
mDNSu32 rrcache_active = 0;
+ mDNSu32 rrcache_totalused = m->rrcache_totalused;
mDNSu32 slot;
AuthRecord *rr;
@@ -15067,9 +15135,9 @@ mDNSexport void mDNS_FinalExit(mDNS *const m)
ReleaseCacheGroup(m, &m->rrcache_hash[slot]);
}
}
- debugf("mDNS_FinalExit: RR Cache was using %ld records, %lu active", m->rrcache_totalused, rrcache_active);
+ debugf("mDNS_FinalExit: RR Cache was using %ld records, %lu active", rrcache_totalused, rrcache_active);
if (rrcache_active != m->rrcache_active)
- LogMsg("*** ERROR *** rrcache_active %lu != m->rrcache_active %lu", rrcache_active, m->rrcache_active);
+ LogMsg("*** ERROR *** rrcache_totalused %lu; rrcache_active %lu != m->rrcache_active %lu", rrcache_totalused, rrcache_active, m->rrcache_active);
for (rr = m->ResourceRecords; rr; rr = rr->next)
LogMsg("mDNS_FinalExit failed to send goodbye for: %p %02X %s", rr, rr->resrec.RecordType, ARDisplayString(m, rr));
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.c
index cb4da6ecef..1243ae77a7 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,13 +13,6 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-
- File: mDNSDebug.c
-
- Contains: Implementation of debugging utilities. Requires a POSIX environment.
-
- Version: 1.0
-
*/
#include "mDNSDebug.h"
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.h b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.h
index 8bf4e5ada8..7bd783c568 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.h
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -148,12 +148,18 @@ extern void LogMsgWithLevel(mDNSLogLevel_t logLevel, const char *format, ...) IS
// (or completely overhauled to use the new "log to a separate file" facility)
#define LogMsgNoIdent LogMsg
+#if APPLE_OSX_mDNSResponder
+extern void LogFatalError(const char *format, ...);
+#else
+#define LogFatalError LogMsg
+#endif
+
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
extern void *mallocL(char *msg, unsigned int size);
extern void freeL(char *msg, void *x);
-extern void LogMemCorruption(const char *format, ...);
extern void uds_validatelists(void);
extern void udns_validatelists(void *const v);
+extern void LogMemCorruption(const char *format, ...);
#else
#define mallocL(X,Y) malloc(Y)
#define freeL(X,Y) free(Y)
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSEmbeddedAPI.h b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSEmbeddedAPI.h
index 75e6fc0991..0b3e646423 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSEmbeddedAPI.h
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSEmbeddedAPI.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -70,6 +70,7 @@
#include "mDNSDebug.h"
#if APPLE_OSX_mDNSResponder
#include <uuid/uuid.h>
+#include <TargetConditionals.h>
#endif
#ifdef __cplusplus
@@ -90,20 +91,14 @@ extern "C" {
// In order to disable the above features pass the option to your compiler, e.g. -D UNICAST_DISABLED
-// Additionally, the LIMITED_RESOURCES_TARGET compile option will eliminate caching and
-// and reduce the maximum DNS message sizes.
+// Additionally, the LIMITED_RESOURCES_TARGET compile option will reduce the maximum DNS message sizes.
#ifdef LIMITED_RESOURCES_TARGET
// Don't support jumbo frames
-#define AbsoluteMaxDNSMessageData 1500
-// By the time you add IPv6 header (40 bytes) UDP header (8 bytes) and DNS message header (12 bytes)
-// this makes 1560 which is 60 bytes over the standard Ethernet MTU. D'oh!
-
+// 40 (IPv6 header) + 8 (UDP header) + 12 (DNS message header) + 1440 (DNS message body) = 1500 total
+#define AbsoluteMaxDNSMessageData 1440
// StandardAuthRDSize is 264 (256+8), which is large enough to hold a maximum-sized SRV record (6 + 256 bytes)
#define MaximumRDSize 264
-// Don't cache anything
-#define AUTH_HASH_SLOTS 1
-#define CACHE_HASH_SLOTS 1
#endif
// ***************************************************************************
@@ -560,7 +555,7 @@ typedef packedstruct
{
mDNSu8 vlen;
mDNSu8 tos;
- mDNSu16 totlen;
+ mDNSOpaque16 totlen;
mDNSOpaque16 id;
mDNSOpaque16 flagsfrags;
mDNSu8 ttl;
@@ -1324,8 +1319,11 @@ enum
enum
{
- DNSServer_FlagDelete = 1,
- DNSServer_FlagNew = 2
+ DNSServer_FlagDelete = 0x1,
+ DNSServer_FlagNew = 0x2,
+#if APPLE_OSX_mDNSResponder
+ DNSServer_FlagUnreachable = 0x4,
+#endif
};
enum
@@ -1417,7 +1415,7 @@ struct ResourceRecord_struct
// that are interface-specific (e.g. address records, especially linklocal addresses)
const domainname *name;
RData *rdata; // Pointer to storage for this rdata
- DNSServer *rDNSServer; // Unicast DNS server authoritative for this entry;null for multicast
+ DNSServer *rDNSServer; // Unicast DNS server authoritative for this entry; null for multicast
AnonymousInfo *AnonInfo; // Anonymous Information
};
@@ -1506,7 +1504,7 @@ struct AuthRecord_struct
AuthRecord *next; // Next in list; first element of structure for efficiency reasons
// Field Group 1: Common ResourceRecord fields
- ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit
+ ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64)
// Field Group 2: Persistent metadata for Authoritative Records
AuthRecord *Additional1; // Recommended additional record to include in response (e.g. SRV for PTR record)
@@ -1638,7 +1636,7 @@ typedef struct ARListElem
struct CacheRecord_struct
{
CacheRecord *next; // Next in list; first element of structure for efficiency reasons
- ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit
+ ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64)
// Transient state for Cache Records
CacheRecord *NextInKAList; // Link to the next element in the chain of known answers to send
@@ -1662,13 +1660,12 @@ struct CacheRecord_struct
CacheRecord *soa; // SOA record to return for proxy questions
mDNSAddr sourceAddress; // node from which we received this record
- // Size to here is 76 bytes when compiling 32-bit; 104 bytes when compiling 64-bit
+ // Size to here is 76 bytes when compiling 32-bit; 104 bytes when compiling 64-bit (now 160 bytes for 64-bit)
RData_small smallrdatastorage; // Storage for small records is right here (4 bytes header + 68 bytes data = 72 bytes)
};
// Should match the CacheGroup_struct members, except namestorage[]. Only used to calculate
-// the size of the namestorage array in CacheGroup_struct so that
-// sizeof(CacheGroup) == sizeof(CacheRecord)
+// the size of the namestorage array in CacheGroup_struct so that sizeof(CacheGroup) == sizeof(CacheRecord)
struct CacheGroup_base
{
CacheGroup *next;
@@ -1891,6 +1888,17 @@ typedef enum { DNSSECValNotRequired = 0, DNSSECValRequired, DNSSECValInProgress,
// RFC 4122 defines it to be 16 bytes
#define UUID_SIZE 16
+#if TARGET_OS_EMBEDDED
+typedef struct
+{
+ domainname * originalQName; // Name of original A/AAAA record if this question is for a CNAME record.
+ mDNSu32 querySendCount; // Number of queries that have been sent to DNS servers so far.
+ mDNSs32 firstQueryTime; // The time when the first query was sent to a DNS server.
+ mDNSBool answered; // Has this question been answered?
+
+} uDNSMetrics;
+#endif
+
struct DNSQuestion_struct
{
// Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
@@ -2001,9 +2009,13 @@ struct DNSQuestion_struct
mDNSu8 ProxyDNSSECOK; // Proxy Question with EDNS0 DNSSEC OK bit set
mDNSs32 pid; // Process ID of the client that is requesting the question
mDNSu8 uuid[UUID_SIZE]; // Unique ID of the client that is requesting the question (valid only if pid is zero)
+ mDNSu32 euid; // Effective User Id of the client that is requesting the question
domainname *qnameOrig; // Copy of the original question name if it is not fully qualified
mDNSQuestionCallback *QuestionCallback;
void *QuestionContext;
+#if TARGET_OS_EMBEDDED
+ uDNSMetrics metrics; // Data used for collecting unicast DNS query metrics.
+#endif
};
typedef struct
@@ -2149,6 +2161,8 @@ struct NetworkInterfaceInfo_struct
mDNSu8 SendGoodbyes; // Send goodbyes on this interface while sleeping
mDNSBool DirectLink; // a direct link, indicating we can skip the probe for
// address records
+ mDNSBool SupportsUnicastMDNSResponse; // Indicates that the interface supports unicast responses
+ // to Bonjour queries. Generally true for an interface.
};
#define SLE_DELETE 0x00000001
@@ -2263,6 +2277,7 @@ typedef struct
mDNSu32 CacheRefreshed; // Number of times the cache was refreshed due to a response
mDNSu32 WakeOnResolves; // Number of times we did a wake on resolve
} mDNSStatistics;
+
extern void LogMDNSStatistics(mDNS *const m);
struct mDNS_struct
@@ -2273,6 +2288,7 @@ struct mDNS_struct
// all required data is passed as parameters to that function.
mDNS_PlatformSupport *p; // Pointer to platform-specific data of indeterminite size
+ mDNSs32 NetworkChanged;
mDNSBool CanReceiveUnicastOn5353;
mDNSBool AdvertiseLocalAddresses;
mDNSBool DivertMulticastAdvertisements; // from interfaces that do not advertise local addresses to local-only
@@ -2372,7 +2388,7 @@ struct mDNS_struct
mDNSs32 ProbeFailTime;
mDNSu32 NumFailedProbes;
mDNSs32 SuppressProbes;
- Platform_t mDNS_plat;
+ Platform_t mDNS_plat; // Why is this here in the “only required for mDNS Responder” section? -- SC
// Unicast-specific data
mDNSs32 NextuDNSEvent; // uDNS next event
@@ -2458,9 +2474,10 @@ struct mDNS_struct
TrustAnchor *TrustAnchors;
int notifyToken;
- int uds_listener_skt; // Listening socket for incoming UDS clients
- mDNSBool mDNSOppCaching; // Opportunistic Caching
+ int uds_listener_skt; // Listening socket for incoming UDS clients. This should not be here -- it's private to uds_daemon.c and nothing to do with mDNSCore -- SC
mDNSu32 AutoTargetServices; // # of services that have AutoTarget set
+ mDNSu32 NumAllInterfaceRecords; // Right now we count *all* multicast records here. Later we may want to change to count interface-specific records separately. (This count includes records on the DuplicateRecords list too.)
+ mDNSu32 NumAllInterfaceQuestions; // Right now we count *all* multicast questions here. Later we may want to change to count interface-specific questions separately.
DNSSECStatistics DNSSECStats;
mDNSStatistics mDNSStats;
@@ -2472,8 +2489,8 @@ struct mDNS_struct
};
#define FORALL_CACHERECORDS(SLOT,CG,CR) \
- for ((SLOT) = 0; (SLOT) < CACHE_HASH_SLOTS; (SLOT)++) \
- for ((CG)=m->rrcache_hash[(SLOT)]; (CG); (CG)=(CG)->next) \
+ for ((SLOT) = 0; (SLOT) < CACHE_HASH_SLOTS; (SLOT)++) \
+ for ((CG)=m->rrcache_hash[(SLOT)]; (CG); (CG)=(CG)->next) \
for ((CR) = (CG)->members; (CR); (CR)=(CR)->next)
// ***************************************************************************
@@ -2534,6 +2551,9 @@ extern const mDNSOpaque64 zeroOpaque64;
extern mDNSBool StrictUnicastOrdering;
extern mDNSu8 NumUnicastDNSServers;
+#if APPLE_OSX_mDNSResponder
+extern mDNSu8 NumUnreachableDNSServers;
+#endif
#define localdomain (*(const domainname *)"\x5" "local")
#define DeviceInfoName (*(const domainname *)"\xC" "_device-info" "\x4" "_tcp")
@@ -2654,7 +2674,6 @@ extern mStatus mDNS_Init (mDNS *const m, mDNS_PlatformSupport *const p,
extern void mDNS_ConfigChanged(mDNS *const m);
extern void mDNS_GrowCache (mDNS *const m, CacheEntity *storage, mDNSu32 numrecords);
-extern void mDNS_GrowAuth (mDNS *const m, AuthEntity *storage, mDNSu32 numrecords);
extern void mDNS_StartExit (mDNS *const m);
extern void mDNS_FinalExit (mDNS *const m);
#define mDNS_Close(m) do { mDNS_StartExit(m); mDNS_FinalExit(m); } while(0)
@@ -2790,7 +2809,7 @@ extern mStatus mDNS_AdvertiseDomains(mDNS *const m, AuthRecord *rr, mDNS_DomainT
#define mDNS_StopAdvertiseDomains mDNS_Deregister
extern mDNSOpaque16 mDNS_NewMessageID(mDNS *const m);
-extern mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr, mDNSBool *myself);
+extern mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr);
extern DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question);
extern mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question);
@@ -3201,6 +3220,7 @@ extern mStatus mDNSPlatformGetPrimaryInterface(mDNS *const m, mDNSAddr *v4, m
extern void mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status);
extern void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, const char *reason);
+extern void mDNSPlatformPreventSleep(mDNS *const m, mDNSu32 timeout, const char *reason);
extern void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration);
extern mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID);
@@ -3323,11 +3343,13 @@ extern void RemoveAutoTunnel6Record(mDNS *const m);
extern mDNSBool RecordReadyForSleep(mDNS *const m, AuthRecord *rr);
// For now this LocalSleepProxy stuff is specific to Mac OS X.
// In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer
-extern mStatus ActivateLocalProxy(mDNS *const m, NetworkInterfaceInfo *const intf);
+extern mStatus ActivateLocalProxy(mDNS *const m, NetworkInterfaceInfo *const intf, mDNSBool *keepaliveOnly);
extern void mDNSPlatformUpdateDNSStatus(mDNS *const m, DNSQuestion *q);
extern void mDNSPlatformTriggerDNSRetry(mDNS *const m, DNSQuestion *v4q, DNSQuestion *v6q);
extern void mDNSPlatformLogToFile(int log_level, const char *buffer);
extern mDNSBool SupportsInNICProxy(NetworkInterfaceInfo *const intf);
+extern mStatus SymptomReporterDNSServerReachable(mDNS *const m, const mDNSAddr *addr);
+extern mStatus SymptomReporterDNSServerUnreachable(DNSServer *s);
#endif
typedef void ProxyCallback (mDNS *const m, void *socket, void *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
@@ -3342,10 +3364,10 @@ extern mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DNSMes
extern void mDNSPlatformSleepAssertion(mDNS *const m, double timeout);
#endif
-extern mDNSBool mDNSPlatformAllowPID(mDNS *const m, DNSQuestion *q);
-extern mDNSs32 mDNSPlatformGetServiceID(mDNS *const m, DNSQuestion *q);
+extern void mDNSPlatformGetDNSRoutePolicy(mDNS *const m, DNSQuestion *q, mDNSBool *isBlocked);
extern void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q);
extern mDNSs32 mDNSPlatformGetPID(void);
+extern mDNSBool mDNSValidKeepAliveRecord(AuthRecord *rr);
// ***************************************************************************
#if 0
@@ -3562,21 +3584,18 @@ struct CompileTimeAssertionChecks_mDNS
char sizecheck_AuthRecord [(sizeof(AuthRecord) <= 1208) ? 1 : -1];
char sizecheck_CacheRecord [(sizeof(CacheRecord) <= 232) ? 1 : -1];
char sizecheck_CacheGroup [(sizeof(CacheGroup) <= 232) ? 1 : -1];
- char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 832) ? 1 : -1];
+ char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 864) ? 1 : -1];
-// Checks commented out when sizeof(DNSQuestion) change cascaded into having to change yet another
-// set of hardcoded size values because these structures contain one or more DNSQuestion
-// instances.
-// char sizecheck_ZoneData [(sizeof(ZoneData) <= 1648) ? 1 : -1];
+ char sizecheck_ZoneData [(sizeof(ZoneData) <= 1700) ? 1 : -1];
char sizecheck_NATTraversalInfo [(sizeof(NATTraversalInfo) <= 200) ? 1 : -1];
char sizecheck_HostnameInfo [(sizeof(HostnameInfo) <= 3050) ? 1 : -1];
char sizecheck_DNSServer [(sizeof(DNSServer) <= 340) ? 1 : -1];
-// char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 6988) ? 1 : -1];
+ char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 7184) ? 1 : -1];
char sizecheck_ServiceRecordSet [(sizeof(ServiceRecordSet) <= 5540) ? 1 : -1];
char sizecheck_DomainAuthInfo [(sizeof(DomainAuthInfo) <= 7888) ? 1 : -1];
-// char sizecheck_ServiceInfoQuery [(sizeof(ServiceInfoQuery) <= 3302) ? 1 : -1];
+ char sizecheck_ServiceInfoQuery [(sizeof(ServiceInfoQuery) <= 3488) ? 1 : -1];
#if APPLE_OSX_mDNSResponder
-// char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1160) ? 1 : -1];
+ char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1208) ? 1 : -1];
#endif
};
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.c
index 5a385e6299..f16e82044a 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -132,18 +132,6 @@ mDNSlocal void SockAddrTomDNSAddr(const struct sockaddr *const sa, mDNSAddr *ipA
}
}
-/*
- * Apple source is using this to set mobile platform
- * specific options.
- */
-/*ARGSUSED*/
-mDNSexport void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q)
-{
- (void)src; /* unused */
- (void)dst; /* unused */
- (void)q; /* unused */
-}
-
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark ***** Send and Receive
#endif
@@ -210,7 +198,7 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms
if (errno == EHOSTDOWN || errno == ENETDOWN || errno == EHOSTUNREACH || errno == ENETUNREACH) return(mStatus_TransientErr);
/* dont report ENETUNREACH */
- if (errno == ENETUNREACH) return(mStatus_TransientErr);
+ if (errno == ENETUNREACH) return(mStatus_TransientErr);
if (MessageCount < 1000)
{
@@ -456,15 +444,19 @@ 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(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
DNameListElem **BrowseDomains, mDNSBool ackConfig)
{
(void) m;
(void) setservers;
- (void) fqdn;
+ if (fqdn) fqdn->c[0] = 0;
(void) setsearch;
- (void) RegDomains;
- (void) BrowseDomains;
+ if (RegDomains) *RegDomains = NULL;
+ if (BrowseDomains) *BrowseDomains = NULL;
(void) ackConfig;
return mDNStrue;
@@ -531,7 +523,7 @@ mDNSexport int ParseDNSServers(mDNS *m, const char *filePath)
numOfServers++;
}
}
- fclose(fp);
+ fclose(fp);
return (numOfServers > 0) ? 0 : -1;
}
@@ -655,10 +647,22 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
// ... with a shared UDP port, if it's for multicast receiving
if (err == 0 && port.NotAnInteger)
{
- #if defined(SO_REUSEPORT)
- err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
- #elif defined(SO_REUSEADDR)
+ // <rdar://problem/20946253>
+ // We test for SO_REUSEADDR first, as suggested by Jonny Törnbom from Axis Communications
+ // Linux kernel versions 3.9 introduces support for socket option
+ // SO_REUSEPORT, however this is not implemented the same as on *BSD
+ // systems. Linux version implements a "port hijacking" prevention
+ // mechanism, limiting processes wanting to bind to an already existing
+ // addr:port to have the same effective UID as the first who bound it. What
+ // this meant for us was that the daemon ran as one user and when for
+ // instance mDNSClientPosix was executed by another user, it wasn't allowed
+ // to bind to the socket. Our suggestion was to switch the order in which
+ // SO_REUSEPORT and SO_REUSEADDR was tested so that SO_REUSEADDR stays on
+ // top and SO_REUSEPORT to be used only if SO_REUSEADDR doesn't exist.
+ #if defined(SO_REUSEADDR) && !defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
+ #elif defined(SO_REUSEPORT)
+ err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
#else
#error This platform has no way to avoid address busy errors on multicast.
#endif
@@ -667,9 +671,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.
@@ -756,11 +760,11 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
struct ipv6_mreq imr6;
struct sockaddr_in6 bindAddr6;
#if defined(IPV6_RECVPKTINFO) // Solaris
- if (err == 0)
- {
- err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_RECVPKTINFO, &kOn, sizeof(kOn));
- if (err < 0) { err = errno; perror("setsockopt - IPV6_RECVPKTINFO"); }
- }
+ if (err == 0)
+ {
+ err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_RECVPKTINFO, &kOn, sizeof(kOn));
+ if (err < 0) { err = errno; perror("setsockopt - IPV6_RECVPKTINFO"); }
+ }
#elif defined(IPV6_PKTINFO)
if (err == 0)
{
@@ -771,11 +775,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)
{
@@ -882,7 +886,7 @@ mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct
assert(intfMask != NULL);
// Allocate the interface structure itself.
- intf = (PosixNetworkInterface*)malloc(sizeof(*intf));
+ intf = (PosixNetworkInterface*)calloc(1, sizeof(*intf));
if (intf == NULL) { assert(0); err = ENOMEM; }
// And make a copy of the intfName.
@@ -937,6 +941,7 @@ mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct
if (strcmp(intfName, STRINGIFY(DIRECTLINK_INTERFACE_NAME)) == 0)
intf->coreIntf.DirectLink = mDNStrue;
#endif
+ intf->coreIntf.SupportsUnicastMDNSResponse = mDNStrue;
// The interface is all ready to go, let's register it with the mDNS core.
if (err == 0)
@@ -1206,11 +1211,6 @@ mDNSlocal mDNSu32 ProcessRoutingNotification(int sd)
case RTM_NEWADDR:
case RTM_DELADDR:
case RTM_IFINFO:
- if (pRSMsg->ifam_type == RTM_IFINFO)
- result |= 1 << ((struct if_msghdr*) pRSMsg)->ifm_index;
- else
- result |= 1 << pRSMsg->ifam_index;
- break;
/*
* ADD & DELETE are happening when IPv6 announces are changing,
* and for some reason it will stop mdnsd to announce IPv6
@@ -1218,7 +1218,11 @@ mDNSlocal mDNSu32 ProcessRoutingNotification(int sd)
*/
case RTM_ADD:
case RTM_DELETE:
- result |= 1;
+ if (pRSMsg->ifam_type == RTM_IFINFO)
+ result |= 1 << ((struct if_msghdr*) pRSMsg)->ifm_index;
+ else
+ result |= 1 << pRSMsg->ifam_index;
+ break;
}
return result;
@@ -1335,7 +1339,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", (int)getpid(), err);
+ fprintf(stderr, "mDNS(%d) WARNING: Unable to detect interface changes (%d).\n",
+ (int)getpid(), err);
err = mStatus_NoError;
}
}
@@ -1624,21 +1629,15 @@ mDNSexport mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID)
return mDNSfalse;
}
-mDNSexport mDNSBool mDNSPlatformAllowPID(mDNS *const m, DNSQuestion *q)
+mDNSexport void mDNSPlatformGetDNSRoutePolicy(mDNS *const m, DNSQuestion *q, mDNSBool *isCellBlocked)
{
(void) m;
- (void) q;
- return mDNStrue;
-}
-mDNSexport mDNSs32 mDNSPlatformGetServiceID(mDNS *const m, DNSQuestion *q)
-{
- (void) m;
- (void) q;
- return -1;
+ q->ServiceID = -1;
+ *isCellBlocked = mDNSfalse;
}
-mDNSexport void mDNSPlatformSetDelegatePID(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q)
+mDNSexport void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q)
{
(void) src;
(void) dst;
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.c
index 026eaae565..0b174e8301 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.c
@@ -87,14 +87,12 @@ void plen_to_mask(int plen, char *addr) {
struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
{
struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
- FILE *fp;
+ 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 ':' */
struct addrinfo hints, *res0;
- struct sockaddr_in6 *sin6;
- struct in6_addr *addrptr;
int err;
int sockfd = -1;
struct ifreq ifr;
@@ -154,18 +152,13 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
char ipv6addr[INET6_ADDRSTRLEN];
plen_to_mask(plen, ipv6addr);
ifi->ifi_netmask = calloc(1, sizeof(struct sockaddr_in6));
- if (ifi->ifi_addr == NULL) {
+ if (ifi->ifi_netmask == NULL) {
goto gotError;
}
- sin6=calloc(1, sizeof(struct sockaddr_in6));
- addrptr=calloc(1, sizeof(struct in6_addr));
- inet_pton(family, ipv6addr, addrptr);
- sin6->sin6_family=family;
- sin6->sin6_addr=*addrptr;
- sin6->sin6_scope_id=scope;
- memcpy(ifi->ifi_netmask, sin6, sizeof(struct sockaddr_in6));
- free(sin6);
+ ((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_family=family;
+ ((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_scope_id=scope;
+ inet_pton(family, ipv6addr, &((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_addr);
/* Add interface name */
memcpy(ifi->ifi_name, ifname, IFI_NAME);
@@ -183,6 +176,7 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
* EADDRNOTAVAIL for the main interface
*/
free(ifi->ifi_addr);
+ free(ifi->ifi_netmask);
free(ifi);
ifipnext = ifiptr;
*ifipnext = ifipold;
@@ -211,6 +205,9 @@ done:
if (sockfd != -1) {
assert(close(sockfd) == 0);
}
+ if (fp != NULL) {
+ fclose(fp);
+ }
return(ifihead); /* pointer to first structure in linked list */
}
#endif // defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
@@ -218,7 +215,7 @@ done:
#if HAVE_SOLARIS
/*
- * Converts prefix length to network mask. Assumes
+ * Converts prefix length to network mask. Assumes
* addr points to a zeroed out buffer and prefix <= sizeof(addr)
* Unlike plen_to_mask returns netmask in binary form and not
* in text form.
@@ -231,10 +228,10 @@ static void plen_to_netmask(int prefix, unsigned char *addr) {
}
/*
- * This function goes through all the IP interfaces associated with a
- * physical interface and finds the best matched one for use by mDNS.
+ * This function goes through all the IP interfaces associated with a
+ * physical interface and finds the best matched one for use by mDNS.
* Returns NULL when none of the IP interfaces associated with a physical
- * interface are usable. Otherwise returns the best matched interface
+ * interface are usable. Otherwise returns the best matched interface
* information and a pointer to the best matched lifreq.
*/
struct ifi_info *
@@ -253,7 +250,7 @@ select_src_ifi_info_solaris(int sockfd, int numifs,
*best_lifr = NULL;
- /*
+ /*
* Check all logical interfaces associated with the physical
* interface and figure out which one works best for us.
*/
@@ -266,7 +263,7 @@ select_src_ifi_info_solaris(int sockfd, int numifs,
if ((chptr = strchr(cmpifname, ':')) != NULL)
*chptr = '\0';
- /*
+ /*
* Check ifname to see if the logical interface is associated
* with the physical interface we are interested in.
*/
@@ -286,7 +283,7 @@ select_src_ifi_info_solaris(int sockfd, int numifs,
if ((ifflags & IFF_UP) == 0)
continue;
/*
- * Avoid address if any of the following flags are set:
+ * Avoid address if any of the following flags are set:
* IFF_NOXMIT: no packets transmitted over interface
* IFF_NOLOCAL: no address
* IFF_PRIVATE: is not advertised
@@ -294,17 +291,17 @@ select_src_ifi_info_solaris(int sockfd, int numifs,
if (ifflags & (IFF_NOXMIT | IFF_NOLOCAL | IFF_PRIVATE))
continue;
- /* A DHCP client will have IFF_UP set yet the address is zero. Ignore */
+ /* A DHCP client will have IFF_UP set yet the address is zero. Ignore */
if (lifr->lifr_addr.ss_family == AF_INET) {
- struct sockaddr_in *sinptr;
+ struct sockaddr_in *sinptr;
- sinptr = (struct sockaddr_in *) &lifr->lifr_addr;
- if (sinptr->sin_addr.s_addr == INADDR_ANY)
- continue;
- }
+ sinptr = (struct sockaddr_in *) &lifr->lifr_addr;
+ if (sinptr->sin_addr.s_addr == INADDR_ANY)
+ continue;
+ }
if (*best_lifr != NULL) {
- /*
+ /*
* Check if we found a better interface by checking
* the flags. If flags are identical we prefer
* the new found interface.
@@ -343,7 +340,7 @@ select_src_ifi_info_solaris(int sockfd, int numifs,
if (ifi == NULL)
return(NULL);
- ifi->ifi_flags = best_lifrflags;
+ ifi->ifi_flags = best_lifrflags;
ifi->ifi_index = if_nametoindex((*best_lifr)->lifr_name);
if (strlcpy(ifi->ifi_name, (*best_lifr)->lifr_name, sizeof(ifi->ifi_name)) >= sizeof(ifi->ifi_name)) {
free(ifi);
@@ -388,7 +385,7 @@ again:
if (ioctl(sockfd, SIOCGLIFNUM, &lifn) < 0)
goto gotError;
/*
- * Pad interface count to detect & retrieve any
+ * Pad interface count to detect & retrieve any
* additional interfaces between IFNUM & IFCONF calls.
*/
lifn.lifn_count += 4;
@@ -416,7 +413,7 @@ again:
if (lifrp->lifr_addr.ss_family != family)
continue;
- /*
+ /*
* See if we have already processed the interface
* by checking the interface names.
*/
@@ -425,12 +422,12 @@ again:
if ((cptr = strchr(ifname, ':')) != NULL)
*cptr = '\0';
- /*
+ /*
* If any of the interfaces found so far share the physical
* interface name then we have already processed the interface.
*/
for (ifi = ifihead; ifi != NULL; ifi = ifi->ifi_next) {
-
+
/* Retrieve physical interface name */
(void) strlcpy(cmpifname, ifi->ifi_name, sizeof(cmpifname));
@@ -444,7 +441,7 @@ again:
if (ifi != NULL)
continue; /* already processed */
- /*
+ /*
* New interface, find the one with the preferred source
* address for our use in Multicast DNS.
*/
@@ -496,7 +493,7 @@ again:
}
ifi->ifi_netmask = malloc(sizeof(struct sockaddr_in));
- if (ifi->ifi_netmask == NULL)
+ if (ifi->ifi_netmask == NULL)
goto gotError;
sinptr = (struct sockaddr_in *) &lifrcopy.lifr_addr;
sinptr->sin_family = AF_INET;
@@ -928,11 +925,11 @@ recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
int nameLen = (sdl->sdl_nlen < IFI_NAME - 1) ? sdl->sdl_nlen : (IFI_NAME - 1);
strncpy(pktp->ipi_ifname, sdl->sdl_data, nameLen);
#endif
- /*
- * the is memcpy used for sparc? no idea;)
- * pktp->ipi_ifindex = sdl->sdl_index;
+ /*
+ * the is memcpy used for sparc? no idea;)
+ * pktp->ipi_ifindex = sdl->sdl_index;
*/
- (void) memcpy(&pktp->ipi_ifindex, CMSG_DATA(cmptr), sizeof(uint_t));
+ (void) memcpy(&pktp->ipi_ifindex, CMSG_DATA(cmptr), sizeof(uint_t));
#ifdef HAVE_BROKEN_RECVIF_NAME
if (sdl->sdl_index == 0) {
pktp->ipi_ifindex = *(uint_t*)sdl;
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/nsec.h b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/nsec.h
index 3dbb841f15..198f57db92 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/nsec.h
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/nsec.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2011-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#ifndef __NSEC_H
#define __NSEC_H
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.c
index f3206a49e1..6ce0158b56 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,6 +51,9 @@ mDNSBool StrictUnicastOrdering = mDNSfalse;
// arbitrary limitation of 64 DNSServers can be removed.
mDNSu8 NumUnicastDNSServers = 0;
#define MAX_UNICAST_DNS_SERVERS 64
+#if APPLE_OSX_mDNSResponder
+mDNSu8 NumUnreachableDNSServers = 0;
+#endif
#define SetNextuDNSEvent(m, rr) { \
if ((m)->NextuDNSEvent - ((rr)->LastAPTime + (rr)->ThisAPInterval) >= 0) \
@@ -162,6 +165,12 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
if (tmp)
{
+#if APPLE_OSX_mDNSResponder
+ if (tmp->flags & DNSServer_FlagDelete)
+ {
+ tmp->flags &= ~DNSServer_FlagUnreachable;
+ }
+#endif
tmp->flags &= ~DNSServer_FlagDelete;
*p = tmp; // move to end of list, to ensure ordering from platform layer
}
@@ -212,6 +221,7 @@ mDNSexport void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 re
{
DNSServer *new;
DNSServer *orig = q->qDNSServer;
+ mDNSu8 rcode = '\0';
mDNS_CheckLock(m);
@@ -223,9 +233,12 @@ mDNSexport void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 re
if (mDNSOpaque16IsZero(q->responseFlags))
q->responseFlags = responseFlags;
+ rcode = (mDNSu8)(responseFlags.b[1] & kDNSFlag1_RC_Mask);
+
// After we reset the qDNSServer to NULL, we could get more SERV_FAILS that might end up
// peanlizing again.
- if (!q->qDNSServer) goto end;
+ if (!q->qDNSServer)
+ goto end;
// If strict ordering of unicast servers needs to be preserved, we just lookup
// the next best match server below
@@ -244,6 +257,10 @@ mDNSexport void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 re
{
LogInfo("PenalizeDNSServer: Not Penalizing PTR question");
}
+ else if ((rcode == kDNSFlag1_RC_FormErr) || (rcode == kDNSFlag1_RC_ServFail) || (rcode == kDNSFlag1_RC_NotImpl) || (rcode == kDNSFlag1_RC_Refused))
+ {
+ LogInfo("PenalizeDNSServer: Not Penalizing DNS Server since it at least responded with rcode %d", rcode);
+ }
else
{
LogInfo("PenalizeDNSServer: Penalizing question type %d", q->qtype);
@@ -607,10 +624,10 @@ mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info, mDNSBool useP
req.reservedMapOp[1] = 0;
req.reservedMapOp[2] = 0;
- if (info->Protocol)
- req.intPort = info->IntPort;
+ if (info->Protocol)
+ req.intPort = info->IntPort;
else
- req.intPort = DiscardPort;
+ req.intPort = DiscardPort;
req.extPort = info->RequestedPort;
// Since we only support IPv4, even if using the all-zeros address, map it, so
@@ -813,11 +830,8 @@ mDNSexport mStatus mDNS_StartNATOperation_internal(mDNS *const m, NATTraversalIn
{
if (traversal == *n)
{
- LogMsg("Error! Tried to add a NAT traversal that's already in the active list: request %p Prot %d Int %d TTL %d",
+ LogFatalError("Error! Tried to add a NAT traversal that's already in the active list: request %p Prot %d Int %d TTL %d",
traversal, traversal->Protocol, mDNSVal16(traversal->IntPort), traversal->NATLease);
- #if ForceAlerts
- *(long*)0 = 0;
- #endif
return(mStatus_AlreadyRegistered);
}
if (traversal->Protocol && traversal->Protocol == (*n)->Protocol && mDNSSameIPPort(traversal->IntPort, (*n)->IntPort) &&
@@ -1841,9 +1855,9 @@ mDNSlocal void GetZoneData_QuestionCallback(mDNS *const m, DNSQuestion *question
LogMsg("GetZoneData_QuestionCallback: Question %##s (%s) ThisQInterval %d not -1", question->qname.c, DNSTypeName(question->qtype), question->ThisQInterval);
zd->Addr.type = mDNSAddrType_IPv4;
if (answer->rdlength == 4)
- zd->Addr.ip.v4 = answer->rdata->u.ipv4;
+ zd->Addr.ip.v4 = answer->rdata->u.ipv4;
else
- zd->Addr.ip.v4 = zerov4Addr;
+ 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
@@ -1898,6 +1912,7 @@ mDNSlocal mStatus GetZoneData_StartQuery(mDNS *const m, ZoneData *zd, mDNSu16 qt
zd->question.qnameOrig = mDNSNULL;
zd->question.AnonInfo = mDNSNULL;
zd->question.pid = mDNSPlatformGetPID();
+ zd->question.euid = 0;
zd->question.QuestionCallback = GetZoneData_QuestionCallback;
zd->question.QuestionContext = zd;
@@ -2587,6 +2602,7 @@ mDNSlocal void GetStaticHostname(mDNS *m)
q->qnameOrig = mDNSNULL;
q->AnonInfo = mDNSNULL;
q->pid = mDNSPlatformGetPID();
+ q->euid = 0;
q->QuestionCallback = FoundStaticHostname;
q->QuestionContext = mDNSNULL;
@@ -4000,6 +4016,10 @@ mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNS
msg->h.numAnswers, msg->h.numAnswers == 1 ? ", " : "s,",
msg->h.numAuthorities, msg->h.numAuthorities == 1 ? "y, " : "ies,",
msg->h.numAdditionals, msg->h.numAdditionals == 1 ? "" : "s", end - msg->data);
+#if APPLE_OSX_mDNSResponder
+ if (NumUnreachableDNSServers > 0)
+ SymptomReporterDNSServerReachable(m, srcaddr);
+#endif
if (QR_OP == StdR)
{
@@ -4150,7 +4170,7 @@ mDNSexport void LLQGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneI
q->servAddr = zeroAddr;
q->servPort = zeroIPPort;
- if (!err && zoneInfo && !mDNSIPPortIsZero(zoneInfo->Port) && !mDNSAddressIsZero(&zoneInfo->Addr) && zoneInfo->Host.c[0])
+ if (!err && !mDNSIPPortIsZero(zoneInfo->Port) && !mDNSAddressIsZero(&zoneInfo->Addr) && zoneInfo->Host.c[0])
{
q->servAddr = zoneInfo->Addr;
q->servPort = zoneInfo->Port;
@@ -4247,10 +4267,14 @@ mDNSlocal void PrivateQueryGotZoneData(mDNS *const m, mStatus err, const ZoneDat
// Called in normal callback context (i.e. mDNS_busy and mDNS_reentrancy are both 1)
mDNSexport void RecordRegistrationGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneData)
{
- AuthRecord *newRR = (AuthRecord*)zoneData->ZoneDataContext;
+ AuthRecord *newRR;
AuthRecord *ptr;
int c1, c2;
+ if (!zoneData) { LogMsg("ERROR: RecordRegistrationGotZoneData invoked with NULL result and no error"); return; }
+
+ newRR = (AuthRecord*)zoneData->ZoneDataContext;
+
if (newRR->nta != zoneData)
LogMsg("RecordRegistrationGotZoneData: nta (%p) != zoneData (%p) %##s (%s)", newRR->nta, zoneData, newRR->resrec.name->c, DNSTypeName(newRR->resrec.rrtype));
@@ -4276,8 +4300,6 @@ mDNSexport void RecordRegistrationGotZoneData(mDNS *const m, mStatus err, const
return;
}
- if (!zoneData) { LogMsg("ERROR: RecordRegistrationGotZoneData invoked with NULL result and no error"); return; }
-
if (newRR->resrec.rrclass != zoneData->ZoneClass)
{
LogMsg("ERROR: New resource record's class (%d) does not match zone class (%d)", newRR->resrec.rrclass, zoneData->ZoneClass);
@@ -4665,7 +4687,7 @@ mDNSlocal void handle_unanswered_query(mDNS *const m)
// Note: req_DO affects only DNSSEC_VALIDATION_SECURE_OPTIONAL questions;
// DNSSEC_VALIDATION_SECURE questions ignores req_DO.
- if (q->qDNSServer && !q->qDNSServer->DNSSECAware && q->qDNSServer->req_DO)
+ if (!q->qDNSServer->DNSSECAware && q->qDNSServer->req_DO)
{
q->qDNSServer->retransDO++;
if (q->qDNSServer->retransDO == MAX_DNSSEC_RETRANSMISSIONS)
@@ -4723,6 +4745,9 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
LogInfo("uDNS_CheckCurrentQuestion: Sent %d unanswered queries for %##s (%s) to %#a:%d (%##s)",
q->unansweredQueries, q->qname.c, DNSTypeName(q->qtype), &orig->addr, mDNSVal16(orig->port), orig->domain.c);
+#if APPLE_OSX_mDNSResponder
+ SymptomReporterDNSServerUnreachable(orig);
+#endif
PenalizeDNSServer(m, q, zeroID);
q->noServerResponse = 1;
}
@@ -4752,7 +4777,7 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
{
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 : zp), 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)
@@ -4798,9 +4823,10 @@ 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);
+ q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL, mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zp), q->unansweredQueries);
if (!q->LocalSocket)
{
q->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
@@ -4808,7 +4834,19 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
mDNSPlatformSetuDNSSocktOpt(q->LocalSocket, &q->qDNSServer->addr, q);
}
if (!q->LocalSocket) err = mStatus_NoMemoryErr; // If failed to make socket (should be very rare), we'll try again next time
- else err = mDNSSendDNSMessage(m, &m->omsg, end, q->qDNSServer->interface, q->LocalSocket, &q->qDNSServer->addr, q->qDNSServer->port, mDNSNULL, mDNSNULL, q->UseBackgroundTrafficClass);
+ else
+ {
+ err = mDNSSendDNSMessage(m, &m->omsg, end, q->qDNSServer->interface, q->LocalSocket, &q->qDNSServer->addr, q->qDNSServer->port, mDNSNULL, mDNSNULL, q->UseBackgroundTrafficClass);
+#if TARGET_OS_EMBEDDED
+ if (!err)
+ {
+ if (q->metrics.querySendCount++ == 0)
+ {
+ q->metrics.firstQueryTime = m->timenow;
+ }
+ }
+#endif
+ }
}
}
@@ -4885,7 +4923,7 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
if (qptr->DuplicateOf == q) { qptr->validDNSServers = q->validDNSServers; qptr->qDNSServer = q->qDNSServer; }
{
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",
+ 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 : zp), q->ThisQInterval);
}
@@ -5023,7 +5061,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
if (!mDNSIPv4AddressIsZero(EffectiveAddress) || cur->retryInterval > NATMAP_INIT_RETRY * 8)
{
const mStatus EffectiveResult = cur->NewResult ? cur->NewResult : mDNSv4AddrIsRFC1918(&EffectiveAddress) ? mStatus_DoubleNAT : mStatus_NoError;
- mDNSIPPort ExternalPort;
+ mDNSIPPort ExternalPort;
if (HaveRoutable)
ExternalPort = cur->IntPort;
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.c b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.c
index 613d78552e..9af68dc95d 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2003-2013 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -171,6 +171,7 @@ struct request_state
struct reply_state *replies; // corresponding (active) reply list
req_termination_fn terminate;
DNSServiceFlags flags;
+ mDNSu32 interfaceIndex;
union
{
@@ -317,10 +318,8 @@ mDNSlocal char *AnonDataToString(const mDNSu8 *ad, int adlen, char *adstr, int a
mDNSlocal void FatalError(char *errmsg)
{
- char* ptr = NULL;
LogMsg("%s: %s", errmsg, dnssd_strerror(dnssd_errno));
- *ptr = 0; // On OS X abort() doesn't generate a crash log, but writing to zero does
- abort(); // On platforms where writing to zero doesn't generate an exception, abort instead
+ abort();
}
mDNSlocal mDNSu32 dnssd_htonl(mDNSu32 l)
@@ -546,10 +545,20 @@ mDNSlocal reply_state *create_reply(const reply_op_t op, const size_t datalen, r
// Append a reply to the list in a request object
// If our request is sharing a connection, then we append our reply_state onto the primary's list
+// If the request does not want asynchronous replies, then the reply is freed instead of being appended to any list.
mDNSlocal void append_reply(request_state *req, reply_state *rep)
{
- request_state *r = req->primary ? req->primary : req;
- reply_state **ptr = &r->replies;
+ request_state *r;
+ reply_state **ptr;
+
+ if (req->no_reply)
+ {
+ freeL("reply_state/append_reply", rep);
+ return;
+ }
+
+ r = req->primary ? req->primary : req;
+ ptr = &r->replies;
while (*ptr) ptr = &(*ptr)->next;
*ptr = rep;
rep->next = NULL;
@@ -662,6 +671,7 @@ mDNSlocal AuthRecord *read_rr_from_ipc_msg(request_state *request, int GetTTL, i
AuthRecType artype;
request->flags = flags;
+ request->interfaceIndex = interfaceIndex;
if (str_err) { LogMsg("ERROR: read_rr_from_ipc_msg - get_string"); return NULL; }
@@ -1066,7 +1076,7 @@ mDNSlocal void regrecord_callback(mDNS *const m, AuthRecord *rr, mStatus result)
if (result != mStatus_MemFree) LogMsg("regrecord_callback: error %d received after parent termination", result);
// We come here when the record is being deregistered either from DNSServiceRemoveRecord or connection_termination.
- // If the record has been updated, we need to free the rdata. Everytime we call mDNS_Update, it calls update_callback
+ // If the record has been updated, we need to free the rdata. Every time we call mDNS_Update, it calls update_callback
// with the old rdata (so that we can free it) and stores the new rdata in "rr->resrec.rdata". This means, we need
// to free the latest rdata for which the update_callback was never called with.
if (rr->resrec.rdata != &rr->rdatastorage) freeL("RData/regrecord_callback", rr->resrec.rdata);
@@ -1151,13 +1161,14 @@ mDNSlocal void set_peer_pid(request_state *request)
return;
mDNSPlatformStrCopy(request->pid_name, proc.pbsi_comm);
request->process_id = p;
+ debugf("set_peer_pid: Client PEERPID is %d %s", p, request->pid_name);
#else // !LOCAL_PEERPID
request->pid_name[0] = '\0';
request->process_id = -1;
+ LogInfo("set_peer_pid: Not Supported on this version of OS");
if (request->sd < 0)
return;
- LogInfo("set_peer_pid: Not Supported on this version of OS");
#endif // LOCAL_PEERPID
}
@@ -1979,7 +1990,6 @@ mDNSlocal mDNSBool PreDefinedInterfaceIndex(mDNSu32 interfaceIndex)
case kDNSServiceInterfaceIndexUnicast:
case kDNSServiceInterfaceIndexP2P:
return mDNStrue;
- break;
default:
return mDNSfalse;
}
@@ -1993,6 +2003,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
domainname d, srv;
mStatus err;
char *AnonData = mDNSNULL;
+ const char *msgTXTData;
DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
@@ -2016,7 +2027,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
// If it's one of the specially defined inteface index values, just return an error.
if (PreDefinedInterfaceIndex(interfaceIndex))
{
- LogMsg("ERROR: handle_regservice_request: bad interfaceIndex %d", interfaceIndex);
+ LogInfo("handle_regservice_request: bad interfaceIndex %d", interfaceIndex);
return(mStatus_BadParamErr);
}
@@ -2033,6 +2044,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
{ LogMsg("ERROR: handle_regservice_request - Couldn't read name/regtype/domain"); return(mStatus_BadParamErr); }
request->flags = flags;
+ request->interfaceIndex = interfaceIndex;
request->u.servicereg.InterfaceID = InterfaceID;
request->u.servicereg.instances = NULL;
request->u.servicereg.txtlen = 0;
@@ -2047,21 +2059,23 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
}
request->u.servicereg.txtlen = get_uint16(&request->msgptr, request->msgend);
+ msgTXTData = get_rdata(&request->msgptr, request->msgend, request->u.servicereg.txtlen);
+
+ if (!request->msgptr) { LogMsg("%3d: DNSServiceRegister(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
+
if (request->u.servicereg.txtlen)
{
request->u.servicereg.txtdata = mallocL("service_info txtdata", request->u.servicereg.txtlen);
if (!request->u.servicereg.txtdata) FatalError("ERROR: handle_regservice_request - malloc");
- mDNSPlatformMemCopy(request->u.servicereg.txtdata, get_rdata(&request->msgptr, request->msgend, request->u.servicereg.txtlen), request->u.servicereg.txtlen);
+ mDNSPlatformMemCopy(request->u.servicereg.txtdata, msgTXTData, request->u.servicereg.txtlen);
}
- if (!request->msgptr) { LogMsg("%3d: DNSServiceRegister(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
-
// Check for sub-types after the service type
request->u.servicereg.num_subtypes = ChopSubTypes(request->u.servicereg.type_as_string, &AnonData); // Note: Modifies regtype string to remove trailing subtypes
if (request->u.servicereg.num_subtypes < 0)
{
LogMsg("ERROR: handle_regservice_request - ChopSubTypes failed %s", request->u.servicereg.type_as_string);
- return(mStatus_BadParamErr);
+ goto bad_param;
}
if (AnonData)
{
@@ -2069,7 +2083,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
if (AnonDataLen > MAX_ANONYMOUS_DATA)
{
LogMsg("ERROR: handle_regservice_request: AnonDataLen %d", AnonDataLen);
- return(mStatus_BadParamErr);
+ goto bad_param;
}
request->u.servicereg.AnonData = mDNStrue;
}
@@ -2080,7 +2094,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
// Don't try to construct "domainname t" until *after* ChopSubTypes has worked its magic
if (!*request->u.servicereg.type_as_string || !MakeDomainNameFromDNSNameString(&request->u.servicereg.type, request->u.servicereg.type_as_string))
- { LogMsg("ERROR: handle_regservice_request - type_as_string bad %s", request->u.servicereg.type_as_string); return(mStatus_BadParamErr); }
+ { LogMsg("ERROR: handle_regservice_request - type_as_string bad %s", request->u.servicereg.type_as_string); goto bad_param; }
if (!name[0])
{
@@ -2096,7 +2110,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
name[newlen] = 0;
}
if (!MakeDomainLabelFromLiteralString(&request->u.servicereg.name, name))
- { LogMsg("ERROR: handle_regservice_request - name bad %s", name); return(mStatus_BadParamErr); }
+ { LogMsg("ERROR: handle_regservice_request - name bad %s", name); goto bad_param; }
request->u.servicereg.autoname = mDNSfalse;
}
@@ -2104,7 +2118,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
{
request->u.servicereg.default_domain = mDNSfalse;
if (!MakeDomainNameFromDNSNameString(&d, domain))
- { LogMsg("ERROR: handle_regservice_request - domain bad %s", domain); return(mStatus_BadParamErr); }
+ { LogMsg("ERROR: handle_regservice_request - domain bad %s", domain); goto bad_param; }
}
else
{
@@ -2113,19 +2127,16 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
}
// We don't allow the anonymous and the regular ones to coexist
- if (!CheckForMixedRegistrations(&request->u.servicereg.type, &d, request->u.servicereg.AnonData))
- {
- return(mStatus_BadParamErr);
- }
+ if (!CheckForMixedRegistrations(&request->u.servicereg.type, &d, request->u.servicereg.AnonData)) { goto bad_param; }
if (!ConstructServiceName(&srv, &request->u.servicereg.name, &request->u.servicereg.type, &d))
{
LogMsg("ERROR: handle_regservice_request - Couldn't ConstructServiceName from, “%#s” “%##s” “%##s”",
- request->u.servicereg.name.c, request->u.servicereg.type.c, d.c); return(mStatus_BadParamErr);
+ request->u.servicereg.name.c, request->u.servicereg.type.c, d.c); goto bad_param;
}
if (!MakeDomainNameFromDNSNameString(&request->u.servicereg.host, host))
- { LogMsg("ERROR: handle_regservice_request - host bad %s", host); return(mStatus_BadParamErr); }
+ { LogMsg("ERROR: handle_regservice_request - host bad %s", host); goto bad_param; }
request->u.servicereg.autorename = (flags & kDNSServiceFlagsNoAutoRename ) == 0;
request->u.servicereg.allowremotequery = (flags & kDNSServiceFlagsAllowRemoteQuery) != 0;
@@ -2172,6 +2183,11 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
}
return(err);
+
+bad_param:
+ freeL("handle_regservice_request (txtdata)", request->u.servicereg.txtdata);
+ request->u.servicereg.txtdata = NULL;
+ return mStatus_BadParamErr;
}
// ***************************************************************************
@@ -2459,9 +2475,13 @@ mDNSlocal void UpdateDeviceInfoRecord(mDNS *const m)
{
int num_autoname = 0;
request_state *req;
+
+ // Don't need to register the device info record for kDNSServiceInterfaceIndexLocalOnly registrations.
for (req = all_requests; req; req = req->next)
- if (req->terminate == regservice_termination_callback && req->u.servicereg.autoname)
+ {
+ if (req->terminate == regservice_termination_callback && req->u.servicereg.autoname && req->interfaceIndex != kDNSServiceInterfaceIndexLocalOnly)
num_autoname++;
+ }
// If DeviceInfo record is currently registered, see if we need to deregister it
if (m->DeviceInfo.resrec.RecordType != kDNSRecordTypeUnregistered)
@@ -2606,7 +2626,7 @@ mDNSlocal mStatus handle_browse_request(request_state *request)
// If it's one of the specially defined inteface index values, just return an error.
if (PreDefinedInterfaceIndex(interfaceIndex))
{
- LogMsg("ERROR: handle_browse_request: bad interfaceIndex %d", interfaceIndex);
+ LogInfo("handle_browse_request: bad interfaceIndex %d", interfaceIndex);
return(mStatus_BadParamErr);
}
@@ -2622,6 +2642,7 @@ mDNSlocal mStatus handle_browse_request(request_state *request)
if (!request->msgptr) { LogMsg("%3d: DNSServiceBrowse(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
request->flags = flags;
+ request->interfaceIndex = interfaceIndex;
typedn.c[0] = 0;
NumSubTypes = ChopSubTypes(regtype, &AnonData); // Note: Modifies regtype string to remove trailing subtypes
if (NumSubTypes < 0 || NumSubTypes > 1)
@@ -2804,7 +2825,7 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
// If it's one of the specially defined inteface index values, just return an error.
if (PreDefinedInterfaceIndex(interfaceIndex))
{
- LogMsg("ERROR: handle_resolve_request: bad interfaceIndex %d", interfaceIndex);
+ LogInfo("handle_resolve_request: bad interfaceIndex %d", interfaceIndex);
return(mStatus_BadParamErr);
}
@@ -2827,6 +2848,7 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
mDNSPlatformMemZero(&request->u.resolve, sizeof(request->u.resolve));
request->flags = flags;
+ request->interfaceIndex = interfaceIndex;
// format questions
request->u.resolve.qsrv.InterfaceID = InterfaceID;
@@ -2854,6 +2876,7 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
request->u.resolve.qsrv.qnameOrig = mDNSNULL;
request->u.resolve.qsrv.AnonInfo = mDNSNULL;
request->u.resolve.qsrv.pid = request->process_id;
+ request->u.resolve.qsrv.euid = request->uid;
request->u.resolve.qsrv.QuestionCallback = resolve_result_callback;
request->u.resolve.qsrv.QuestionContext = request;
@@ -2882,6 +2905,7 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
request->u.resolve.qtxt.qnameOrig = mDNSNULL;
request->u.resolve.qtxt.AnonInfo = mDNSNULL;
request->u.resolve.qtxt.pid = request->process_id;
+ request->u.resolve.qtxt.euid = request->uid;
request->u.resolve.qtxt.QuestionCallback = resolve_result_callback;
request->u.resolve.qtxt.QuestionContext = request;
@@ -3167,6 +3191,7 @@ mDNSlocal mStatus SendAdditionalQuery(DNSQuestion *q, request_state *request, mS
q2->TimeoutQuestion = 0;
q2->AnonInfo = mDNSNULL;
q2->pid = request->process_id;
+ q2->euid = request->uid;
}
LogOperation("%3d: DNSServiceQueryRecord(%##s, %s) unicast", request->sd, q2->qname.c, DNSTypeName(q2->qtype));
err = mDNS_StartQuery(&mDNSStorage, q2);
@@ -3346,15 +3371,16 @@ mDNSlocal void queryrecord_result_reply(mDNS *const m, request_state *req, DNSQu
(x.cr_version == XUCRED_VERSION))
{
struct sockaddr_storage addr;
- const RDataBody2 *const rdb = (RDataBody2 *)answer->rdata->u.data;
addr.ss_len = 0;
if (answer->rrtype == kDNSType_A || answer->rrtype == kDNSType_AAAA)
{
if (answer->rrtype == kDNSType_A)
{
- struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
+ struct sockaddr_in *const sin = (struct sockaddr_in *)&addr;
sin->sin_port = 0;
- if (!putRData(mDNSNULL, (mDNSu8 *)&sin->sin_addr, (mDNSu8 *)(&sin->sin_addr + sizeof(rdb->ipv4)), answer))
+ // Instead of this stupid call to putRData it would be much simpler to just assign the value in the sensible way, like this:
+ // sin->sin_addr.s_addr = answer->rdata->u.ipv4.NotAnInteger;
+ if (!putRData(mDNSNULL, (mDNSu8 *)&sin->sin_addr, (mDNSu8 *)(&sin->sin_addr + sizeof(mDNSv4Addr)), answer))
LogMsg("queryrecord_result_reply: WCF AF_INET putRData failed");
else
{
@@ -3364,9 +3390,14 @@ mDNSlocal void queryrecord_result_reply(mDNS *const m, request_state *req, DNSQu
}
else if (answer->rrtype == kDNSType_AAAA)
{
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
+ struct sockaddr_in6 *const sin6 = (struct sockaddr_in6 *)&addr;
sin6->sin6_port = 0;
- if (!putRData(mDNSNULL, (mDNSu8 *)&sin6->sin6_addr, (mDNSu8 *)(&sin6->sin6_addr + sizeof(rdb->ipv6)), answer))
+ // Instead of this stupid call to putRData it would be much simpler to just assign the value in the sensible way, like this:
+ // sin6->sin6_addr.__u6_addr.__u6_addr32[0] = answer->rdata->u.ipv6.l[0];
+ // sin6->sin6_addr.__u6_addr.__u6_addr32[1] = answer->rdata->u.ipv6.l[1];
+ // sin6->sin6_addr.__u6_addr.__u6_addr32[2] = answer->rdata->u.ipv6.l[2];
+ // sin6->sin6_addr.__u6_addr.__u6_addr32[3] = answer->rdata->u.ipv6.l[3];
+ if (!putRData(mDNSNULL, (mDNSu8 *)&sin6->sin6_addr, (mDNSu8 *)(&sin6->sin6_addr + sizeof(mDNSv6Addr)), answer))
LogMsg("queryrecord_result_reply: WCF AF_INET6 putRData failed");
else
{
@@ -3662,7 +3693,7 @@ mDNSlocal void queryrecord_termination_callback(request_state *request)
mDNSlocal void SetQuestionPolicy(DNSQuestion *q, request_state *req)
{
int i;
-
+ q->euid = req->uid;
// The policy is either based on pid or UUID. Pass a zero pid
// to the "core" if the UUID is valid. If we always pass the pid,
// then the "core" needs to determine whether the uuid is valid
@@ -3685,6 +3716,8 @@ mDNSlocal void SetQuestionPolicy(DNSQuestion *q, request_state *req)
{
q->pid = req->process_id;
}
+
+ //debugf("SetQuestionPolicy: q->euid[%d] q->pid[%d] uuid is valid : %s", q->euid, q->pid, req->validUUID ? "true" : "false");
}
mDNSlocal mStatus handle_queryrecord_request(request_state *request)
@@ -3703,9 +3736,11 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
if (interfaceIndex && !InterfaceID)
{
// If it's one of the specially defined inteface index values, just return an error.
- if (PreDefinedInterfaceIndex(interfaceIndex))
+ // Also, caller should return an error immediately if lo0 (index 1) is not configured
+ // into the current active interfaces. See background in Radar 21967160.
+ if (PreDefinedInterfaceIndex(interfaceIndex) || interfaceIndex == 1)
{
- LogMsg("ERROR: handle_queryrecord_request: bad interfaceIndex %d", interfaceIndex);
+ LogInfo("handle_queryrecord_request: bad interfaceIndex %d", interfaceIndex);
return(mStatus_BadParamErr);
}
@@ -3723,6 +3758,7 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
{ LogMsg("%3d: DNSServiceQueryRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
request->flags = flags;
+ request->interfaceIndex = interfaceIndex;
mDNSPlatformMemZero(&request->u.queryrecord, sizeof(request->u.queryrecord));
q->InterfaceID = InterfaceID;
@@ -3792,12 +3828,14 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
q->qnameOrig = mDNSNULL;
SetQuestionPolicy(q, request);
- LogOperation("%3d: DNSServiceQueryRecord(%X, %d, %##s, %s) START PID[%d](%s)",
+ LogOperation("%3d: DNSServiceQueryRecord(%X, %d, %##s, %s) START PID[%d](%s)",
request->sd, flags, interfaceIndex, q->qname.c, DNSTypeName(q->qtype), request->process_id, request->pid_name);
err = mDNS_StartQuery(&mDNSStorage, q);
- if (err)
+ if (err)
+ {
LogMsg("%3d: ERROR: DNSServiceQueryRecord %##s %s mDNS_StartQuery: %d", request->sd, q->qname.c, DNSTypeName(q->qtype), (int)err);
+ }
else
{
request->terminate = queryrecord_termination_callback;
@@ -3911,6 +3949,9 @@ mDNSlocal mStatus handle_enum_request(request_state *request)
if (!request->msgptr)
{ LogMsg("%3d: DNSServiceEnumerateDomains(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
+ request->flags = flags;
+ request->interfaceIndex = interfaceIndex;
+
// mark which kind of enumeration we're doing so that we know what domain enumeration queries to stop
request->u.enumeration.flags = reg;
@@ -4084,7 +4125,7 @@ mDNSlocal void handle_connection_delegate_request(request_state *request)
if (proc_pidinfo(request->process_id, PROC_PIDT_SHORTBSDINFO, 1, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) == 0)
return;
mDNSPlatformStrCopy(request->pid_name, proc.pbsi_comm);
- //LogMsg("handle_connection_delegate_request: process id %d, name %s", request->process_id, request->pid_name);
+ debugf("handle_connection_delegate_request: process id %d, name %s", request->process_id, request->pid_name);
}
#endif
#ifdef LOCAL_PEEREUUID
@@ -4118,7 +4159,7 @@ mDNSlocal void handle_getpid_request(request_state *request)
const DNSQuestion *q = NULL;
PIDInfo pi;
- LogOperation("%3d: DNSServiceGetPID START", request->sd);
+ LogMsg("%3d: DNSServiceGetPID START", request->sd);
for (req = all_requests; req; req=req->next)
{
@@ -4135,7 +4176,7 @@ mDNSlocal void handle_getpid_request(request_state *request)
if (port == srcport)
{
pid = req->process_id;
- LogInfo("DNSServiceGetPID: srcport %d, pid %d [%s] question %##s", htons(srcport), pid, req->pid_name, q->qname.c);
+ LogMsg("DNSServiceGetPID: srcport %d, pid %d [%s] question %##s", htons(srcport), pid, req->pid_name, q->qname.c);
break;
}
}
@@ -4154,7 +4195,7 @@ mDNSlocal void handle_getpid_request(request_state *request)
#if APPLE_OSX_mDNSResponder
pid = getpid();
#endif // APPLE_OSX_mDNSResponder
- LogInfo("DNSServiceGetPID: srcport %d, pid %d [%s], question %##s", htons(srcport), pid, "_mDNSResponder", q->qname.c);
+ LogMsg("DNSServiceGetPID: srcport %d, pid %d [%s], question %##s", htons(srcport), pid, "_mDNSResponder", q->qname.c);
break;
}
}
@@ -4164,7 +4205,7 @@ mDNSlocal void handle_getpid_request(request_state *request)
pi.err = 0;
pi.pid = pid;
send_all(request->sd, (const char *)&pi, sizeof(PIDInfo));
- LogOperation("%3d: DNSServiceGetPID STOP", request->sd);
+ LogMsg("%3d: DNSServiceGetPID STOP", request->sd);
}
// ***************************************************************************
@@ -4262,6 +4303,8 @@ mDNSlocal mStatus handle_port_mapping_request(request_state *request)
if (!(protocol & (kDNSServiceProtocol_UDP | kDNSServiceProtocol_TCP))) return(mStatus_BadParamErr);
}
+ request->flags = flags;
+ request->interfaceIndex = interfaceIndex;
request->u.pm.NATinfo.Protocol = !protocol ? NATOp_AddrRequest : (protocol == kDNSServiceProtocol_UDP) ? NATOp_MapUDP : NATOp_MapTCP;
// u.pm.NATinfo.IntPort = already set above
request->u.pm.NATinfo.RequestedPort = request->u.pm.ReqExt;
@@ -4385,6 +4428,7 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
domainname d;
mStatus err = 0;
mDNSs32 serviceIndex = -1; // default unscoped value for ServiceID is -1
+ mDNSInterfaceID InterfaceID;
DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
@@ -4402,7 +4446,7 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
mDNSPlatformMemZero(&request->u.addrinfo, sizeof(request->u.addrinfo));
- mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
+ InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
// The request is scoped to a specific interface index, but the
// interface is not currently in our list.
@@ -4411,7 +4455,7 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
// If it's one of the specially defined inteface index values, just return an error.
if (PreDefinedInterfaceIndex(interfaceIndex))
{
- LogMsg("ERROR: handle_addrinfo_request: bad interfaceIndex %d", interfaceIndex);
+ LogInfo("handle_addrinfo_request: bad interfaceIndex %d", interfaceIndex);
return(mStatus_BadParamErr);
}
@@ -4420,6 +4464,9 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
InterfaceID = (mDNSInterfaceID)(uintptr_t)interfaceIndex;
LogInfo("handle_addrinfo_request: query pending for interface index %d", interfaceIndex);
}
+
+ request->flags = flags;
+ request->interfaceIndex = interfaceIndex;
request->u.addrinfo.interface_id = InterfaceID;
request->u.addrinfo.flags = flags;
request->u.addrinfo.protocol = get_uint32(&request->msgptr, request->msgend);
@@ -4558,8 +4605,7 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
}
}
- LogOperation("%3d: DNSServiceGetAddrInfo(%X, %d, %d, %##s) START PID[%d](%s)", request->sd, flags, interfaceIndex,
- request->u.addrinfo.protocol, d.c, request->process_id, request->pid_name);
+ LogOperation("%3d: DNSServiceGetAddrInfo(%X, %d, %d, %##s) START PID[%d](%s)", request->sd, flags, interfaceIndex, request->u.addrinfo.protocol, d.c, request->process_id, request->pid_name);
return(err);
}
@@ -4664,12 +4710,10 @@ mDNSlocal void read_msg(request_state *req)
#if !defined(_WIN32)
cmsg = CMSG_FIRSTHDR(&msg);
#if DEBUG_64BIT_SCM_RIGHTS
- LogMsg("%3d: Expecting %d %d %d %d", req->sd, sizeof(cbuf), sizeof(cbuf), SOL_SOCKET, SCM_RIGHTS);
- LogMsg("%3d: Got %d %d %d %d", req->sd, msg.msg_controllen, cmsg->cmsg_len, cmsg->cmsg_level, cmsg->cmsg_type);
+ LogMsg("%3d: Expecting %d %d %d %d", req->sd, sizeof(cbuf), sizeof(cbuf), SOL_SOCKET, SCM_RIGHTS);
+ LogMsg("%3d: Got %d %d %d %d", req->sd, msg.msg_controllen, cmsg ? cmsg->cmsg_len : -1, cmsg ? cmsg->cmsg_level : -1, cmsg ? cmsg->cmsg_type : -1);
#endif // DEBUG_64BIT_SCM_RIGHTS
- if (msg.msg_controllen != 0 &&
- cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_RIGHTS)
+ if (cmsg && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
{
#if APPLE_OSX_mDNSResponder
// Strictly speaking BPF_fd belongs solely in the platform support layer, but because
@@ -4689,7 +4733,7 @@ mDNSlocal void read_msg(request_state *req)
#endif // DEBUG_64BIT_SCM_RIGHTS
if (req->data_bytes < req->hdr.datalen)
{
- LogMsg("%3d: Client(PID [%d](%s)) sent error socket %d via SCM_RIGHTS with req->data_bytes %d < req->hdr.datalen %d",
+ LogMsg("%3d: Client(PID [%d](%s)) sent result code socket %d via SCM_RIGHTS with req->data_bytes %d < req->hdr.datalen %d",
req->sd, req->process_id, req->pid_name, req->errsd, req->data_bytes, req->hdr.datalen);
req->ts = t_error;
return;
@@ -4756,7 +4800,7 @@ mDNSlocal void read_msg(request_state *req)
#if !defined(USE_TCP_LOOPBACK)
got_errfd:
#endif
- LogOperation("%3d: Error socket %d created %08X %08X", req->sd, req->errsd, req->hdr.client_context.u32[1], req->hdr.client_context.u32[0]);
+ 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]);
#if defined(_WIN32)
if (ioctlsocket(req->errsd, FIONBIO, &opt) != 0)
#else
@@ -4861,9 +4905,6 @@ mDNSlocal void request_callback(int fd, short filter, void *info)
return;
}
- // check if client wants silent operation
- if (req->hdr.ipc_flags & IPC_FLAGS_NOREPLY) req->no_reply = 1;
-
// If req->terminate is already set, this means this operation is sharing an existing connection
if (req->terminate && !LightweightOp(req->hdr.op))
{
@@ -4901,6 +4942,9 @@ mDNSlocal void request_callback(int fd, short filter, void *info)
req = newreq;
}
+ // Check if the request wants no asynchronous replies.
+ if (req->hdr.ipc_flags & IPC_FLAGS_NOREPLY) req->no_reply = 1;
+
// If we're shutting down, don't allow new client requests
// We do allow "cancel" and "getproperty" during shutdown
if (mDNSStorage.ShutdownTime && req->hdr.op != cancel_request && req->hdr.op != getproperty_request)
@@ -4958,7 +5002,7 @@ 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: Error socket %d closed %08X %08X (%d)",
+ 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);
dnssd_close(req->errsd);
req->errsd = req->sd;
@@ -5023,11 +5067,14 @@ mDNSlocal void connect_callback(int fd, short filter, void *info)
#if APPLE_OSX_mDNSResponder
struct xucred x;
socklen_t xucredlen = sizeof(x);
- if (getsockopt(sd, 0, LOCAL_PEERCRED, &x, &xucredlen) >= 0 && x.cr_version == XUCRED_VERSION) request->uid = x.cr_uid;
- else my_perror("ERROR: getsockopt, LOCAL_PEERCRED");
+ if (getsockopt(sd, 0, LOCAL_PEERCRED, &x, &xucredlen) >= 0 && x.cr_version == XUCRED_VERSION)
+ request->uid = x.cr_uid; // save the effective userid of the client
+ else
+ my_perror("ERROR: getsockopt, LOCAL_PEERCRED");
+
debugf("LOCAL_PEERCRED %d %u %u %d", xucredlen, x.cr_version, x.cr_uid, x.cr_ngroups);
#endif // APPLE_OSX_mDNSResponder
- LogOperation("%3d: Adding FD for uid %u", request->sd, request->uid);
+ LogOperation("%3d: connect_callback: Adding FD for uid %u", request->sd, request->uid);
udsSupportAddFDToEventLoop(sd, request_callback, request, &request->platform_data);
}
}
@@ -5068,7 +5115,7 @@ mDNSlocal mDNSBool uds_socket_setup(dnssd_sock_t skt)
}
else
{
- LogInfo("%3d: Listening for incoming Unix Domain Socket client requests", skt);
+ LogOperation("%3d: Listening for incoming Unix Domain Socket client requests", skt);
mDNSStorage.uds_listener_skt = skt;
}
return mDNStrue;
@@ -5248,8 +5295,8 @@ mDNSlocal void LogClientInfo(mDNS *const m, request_state *req)
prefix, num_records, num_records != 1 ? "s" : "", num_ops, num_ops != 1 ? "s" : "",
req->process_id, req->pid_name);
for (p = req->u.reg_recs; p; p=p->next)
- LogMsgNoIdent(" -> DNSServiceRegisterRecord %3d %s PID[%d](%s)", p->key, ARDisplayString(m, p->rr),
- req->process_id, req->pid_name);
+ LogMsgNoIdent(" -> DNSServiceRegisterRecord 0x%08X %2d %3d %s PID[%d](%s)",
+ req->flags, req->interfaceIndex, p->key, ARDisplayString(m, p->rr), req->process_id, req->pid_name);
for (r = req->next; r; r=r->next) if (r->primary == req) LogClientInfo(m, r);
}
else if (req->terminate == regservice_termination_callback)
@@ -5257,32 +5304,34 @@ mDNSlocal void LogClientInfo(mDNS *const m, request_state *req)
service_instance *ptr;
char anonstr[256];
for (ptr = req->u.servicereg.instances; ptr; ptr = ptr->next)
- LogMsgNoIdent("%s DNSServiceRegister %##s%s %u/%u PID[%d](%s)",
- (ptr == req->u.servicereg.instances) ? prefix : " ", ptr->srs.RR_SRV.resrec.name->c,
- AnonDataToString(ptr->srs.AnonData, 0, anonstr, sizeof(anonstr)), mDNSVal16(req->u.servicereg.port),
- SRS_PORT(&ptr->srs), req->process_id, req->pid_name);
+ LogMsgNoIdent("%s DNSServiceRegister 0x%08X %2d %##s%s %u/%u PID[%d](%s)",
+ (ptr == req->u.servicereg.instances) ? prefix : " ", req->flags, req->interfaceIndex, ptr->srs.RR_SRV.resrec.name->c,
+ AnonDataToString(ptr->srs.AnonData, 0, anonstr, sizeof(anonstr)), mDNSVal16(req->u.servicereg.port),
+ SRS_PORT(&ptr->srs), req->process_id, req->pid_name);
}
else if (req->terminate == browse_termination_callback)
{
browser_t *blist;
char anonstr[256];
for (blist = req->u.browser.browsers; blist; blist = blist->next)
- LogMsgNoIdent("%s DNSServiceBrowse %##s%s PID[%d](%s)",
- (blist == req->u.browser.browsers) ? prefix : " ",blist->q.qname.c,
- AnonDataToString(req->u.browser.AnonData, 0, anonstr, sizeof(anonstr)), req->process_id, req->pid_name);
+ LogMsgNoIdent("%s DNSServiceBrowse 0x%08X %2d %##s%s PID[%d](%s)",
+ (blist == req->u.browser.browsers) ? prefix : " ", req->flags, req->interfaceIndex, blist->q.qname.c,
+ AnonDataToString(req->u.browser.AnonData, 0, anonstr, sizeof(anonstr)), req->process_id, req->pid_name);
}
else if (req->terminate == resolve_termination_callback)
- LogMsgNoIdent("%s DNSServiceResolve %##s PID[%d](%s)",
- prefix, req->u.resolve.qsrv.qname.c, req->process_id, req->pid_name);
+ LogMsgNoIdent("%s DNSServiceResolve 0x%08X %2d %##s PID[%d](%s)",
+ prefix, req->flags, req->interfaceIndex, req->u.resolve.qsrv.qname.c, req->process_id, req->pid_name);
else if (req->terminate == queryrecord_termination_callback)
- LogMsgNoIdent("%s DNSServiceQueryRecord %##s (%s) PID[%d](%s)",
- prefix, req->u.queryrecord.q.qname.c, DNSTypeName(req->u.queryrecord.q.qtype), req->process_id, req->pid_name);
+ LogMsgNoIdent("%s DNSServiceQueryRecord 0x%08X %2d %##s (%s) PID[%d](%s)",
+ prefix, req->flags, req->interfaceIndex, req->u.queryrecord.q.qname.c, DNSTypeName(req->u.queryrecord.q.qtype), req->process_id, req->pid_name);
else if (req->terminate == enum_termination_callback)
- LogMsgNoIdent("%s DNSServiceEnumerateDomains %##s PID[%d](%s)", prefix, req->u.enumeration.q_all.qname.c,
- req->process_id, req->pid_name);
+ LogMsgNoIdent("%s DNSServiceEnumerateDomains 0x%08X %2d %##s PID[%d](%s)",
+ prefix, req->flags, req->interfaceIndex, req->u.enumeration.q_all.qname.c, req->process_id, req->pid_name);
else if (req->terminate == port_mapping_termination_callback)
- LogMsgNoIdent("%s DNSServiceNATPortMapping %s%s Int %5d Req %5d Ext %.4a:%5d Req TTL %5d Granted TTL %5d PID[%d](%s)",
+ LogMsgNoIdent("%s DNSServiceNATPortMapping 0x%08X %2d %s%s Int %5d Req %5d Ext %.4a:%5d Req TTL %5d Granted TTL %5d PID[%d](%s)",
prefix,
+ req->flags,
+ req->interfaceIndex,
req->u.pm.NATinfo.Protocol & NATOp_MapTCP ? "TCP" : " ",
req->u.pm.NATinfo.Protocol & NATOp_MapUDP ? "UDP" : " ",
mDNSVal16(req->u.pm.NATinfo.IntPort),
@@ -5293,7 +5342,8 @@ mDNSlocal void LogClientInfo(mDNS *const m, request_state *req)
req->u.pm.NATinfo.Lifetime,
req->process_id, req->pid_name);
else if (req->terminate == addrinfo_termination_callback)
- LogMsgNoIdent("%s DNSServiceGetAddrInfo %s%s %##s PID[%d](%s)", prefix,
+ LogMsgNoIdent("%s DNSServiceGetAddrInfo 0x%08X %2d %s%s %##s PID[%d](%s)",
+ prefix, req->flags, req->interfaceIndex,
req->u.addrinfo.protocol & kDNSServiceProtocol_IPv4 ? "v4" : " ",
req->u.addrinfo.protocol & kDNSServiceProtocol_IPv6 ? "v6" : " ",
req->u.addrinfo.q4.qname.c, req->process_id, req->pid_name);
@@ -5527,19 +5577,22 @@ mDNSlocal void LogOneAuthRecord(mDNS *const m, const AuthRecord *ar, mDNSs32 now
char anstr[256];
if (AuthRecord_uDNS(ar))
{
- LogMsgNoIdent("%7d %7d %7d %7d %s",
+ LogMsgNoIdent("%7d %7d %7d %7d %s %s",
ar->ThisAPInterval / mDNSPlatformOneSecond,
(ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond,
ar->expire ? (ar->expire - now) / mDNSPlatformOneSecond : 0,
- ar->state, ARDisplayString(m, ar));
+ ar->state,
+ ar->AllowRemoteQuery ? "☠" : " ",
+ ARDisplayString(m, ar));
}
else
{
- LogMsgNoIdent("%7d %7d %7d %7s %s%s",
+ LogMsgNoIdent("%7d %7d %7d %7s %s %s%s",
ar->ThisAPInterval / mDNSPlatformOneSecond,
ar->AnnounceCount ? (ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond : 0,
ar->TimeExpire ? (ar->TimeExpire - now) / mDNSPlatformOneSecond : 0,
ifname ? ifname : "ALL",
+ ar->AllowRemoteQuery ? "☠" : " ",
ARDisplayString(m, ar), AnonInfoToString(ar->resrec.AnonInfo, anstr, sizeof(anstr)));
}
}
@@ -5992,11 +6045,8 @@ foundparent:;
LogMsgNoIdent("m->WABBrowseQueriesCount %d", m->WABBrowseQueriesCount);
LogMsgNoIdent("m->WABLBrowseQueriesCount %d", m->WABLBrowseQueriesCount);
LogMsgNoIdent("m->WABRegQueriesCount %d", m->WABRegQueriesCount);
- LogMsgNoIdent("m->mDNSOppCaching %d", m->mDNSOppCaching);
LogMsgNoIdent("m->AutoTargetServices %d", m->AutoTargetServices);
-#define LogTimer(MSG,T) LogMsgNoIdent( MSG " %08X %11d %08X %11d", (T), (T), (T)-now, (T)-now)
-
LogMsgNoIdent(" ABS (hex) ABS (dec) REL (hex) REL (dec)");
LogMsgNoIdent("m->timenow %08X %11d", now, now);
LogMsgNoIdent("m->timenow_adjust %08X %11d", m->timenow_adjust, m->timenow_adjust);
@@ -6101,7 +6151,6 @@ mDNSlocal int send_msg(request_state *const req)
{
reply_state *const rep = req->replies; // Send the first waiting reply
ssize_t nwriten;
- if (req->no_reply) return(t_complete);
ConvertHeaderBytes(rep->mhdr);
nwriten = send(req->sd, (char *)&rep->mhdr + rep->nwriten, rep->totallen - rep->nwriten, 0);
@@ -6163,7 +6212,7 @@ mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent)
}
else if (result == t_terminated || result == t_error)
{
- LogMsg("%3d: Could not write data to clientPID[%d](%s) because of error - aborting connection", r->sd, r->process_id, r->pid_name);
+ LogMsg("%3d: Could not write data to client PID[%d](%s) because of error - aborting connection", r->sd, r->process_id, r->pid_name);
LogClientInfo(&mDNSStorage, r);
abort_request(r);
}
@@ -6219,7 +6268,7 @@ struct CompileTimeAssertionChecks_uds_daemon
char sizecheck_request_state [(sizeof(request_state) <= 2000) ? 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) <= 1096) ? 1 : -1];
+ char sizecheck_browser_t [(sizeof(browser_t) <= 1128) ? 1 : -1];
char sizecheck_reply_hdr [(sizeof(reply_hdr) <= 12) ? 1 : -1];
char sizecheck_reply_state [(sizeof(reply_state) <= 64) ? 1 : -1];
};
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.h b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.h
index ca361172d1..6cc9197d63 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.h
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,13 +13,6 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-
- File: uds_daemon.h
-
- Contains: Interfaces necessary to talk to uds_daemon.c.
-
- Version: 1.0
-
*/
#include "mDNSEmbeddedAPI.h"
@@ -29,6 +22,8 @@
#define SRS_PORT(S) mDNSVal16((S)->RR_SRV.resrec.rdata->u.srv.port)
+#define LogTimer(MSG,T) LogMsgNoIdent( MSG " %08X %11d %08X %11d", (T), (T), (T)-now, (T)-now)
+
extern int udsserver_init(dnssd_sock_t skts[], mDNSu32 count);
extern mDNSs32 udsserver_idle(mDNSs32 nextevent);
extern void udsserver_info(mDNS *const m); // print out info about current state
diff --git a/usr/src/lib/libdns_sd/README b/usr/src/lib/libdns_sd/README
index 81491ffd91..9bae6c7404 100644
--- a/usr/src/lib/libdns_sd/README
+++ b/usr/src/lib/libdns_sd/README
@@ -21,8 +21,7 @@
#
# CDDL HEADER END
#
-# Copyright 2016 Toomas Soome <tsoome@me.com>
-#
+Updated from upstream version mDNSResponder-625.41.2
Updated from upstream version mDNSResponder-576.30.4
Multicast DNS and Service Discovery support in Solaris using the
diff --git a/usr/src/lib/libdns_sd/common/dns_sd.h b/usr/src/lib/libdns_sd/common/dns_sd.h
index 3831527313..cf32ea1eda 100644
--- a/usr/src/lib/libdns_sd/common/dns_sd.h
+++ b/usr/src/lib/libdns_sd/common/dns_sd.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2003-2013 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003-2015 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:
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@@ -66,7 +66,7 @@
*/
#ifndef _DNS_SD_H
-#define _DNS_SD_H 5763004
+#define _DNS_SD_H 6254102
#ifdef __cplusplus
extern "C" {
@@ -497,12 +497,18 @@ enum
* as the "serviceIndex".
*/
- kDNSServiceFlagsDenyExpensive = 0x20000000
+ kDNSServiceFlagsDenyExpensive = 0x20000000,
/*
* This flag is meaningful only for Unicast DNS queries. When set, the kernel will restrict
* DNS resolutions on interfaces defined as expensive for that request.
*/
+ kDNSServiceFlagsPathEvaluationDone = 0x40000000
+ /*
+ * This flag is meaningful for only Unicast DNS queries.
+ * When set, it indicates that Network PathEvaluation has already been performed.
+ */
+
};
#define kDNSServiceOutputFlags (kDNSServiceFlagsValidate | kDNSServiceFlagsValidateOptional | kDNSServiceFlagsMoreComing | kDNSServiceFlagsAdd | kDNSServiceFlagsDefault)
@@ -724,9 +730,8 @@ enum
* DNS server." Normally, most clients will use 0 for interface index to
* automatically get the default sensible behaviour.
*
- * If the client passes a positive interface index, then for multicast names that
- * indicates to do the operation only on that one interface. For unicast names the
- * interface index is ignored unless kDNSServiceFlagsForceMulticast is also set.
+ * If the client passes a positive interface index, then that indicates to do the
+ * operation only on that one specified interface.
*
* If the client passes kDNSServiceInterfaceIndexLocalOnly when registering
* a service, then that service will be found *only* by other local clients
@@ -2606,34 +2611,6 @@ DNSServiceErrorType DNSSD_API DNSServiceSleepKeepalive
);
#endif
-#ifdef APPLE_OSX_mDNSResponder
-/* DNSServiceCreateDelegateConnection()
- *
- * Create a delegate connection to the daemon allowing efficient registration of
- * multiple individual records.
- *
- * Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. Deallocating
- * the reference (via DNSServiceRefDeallocate()) severs the
- * connection and deregisters all records registered on this connection.
- *
- * pid : Process ID of the delegate
- *
- * uuid: UUID of the delegate
- *
- * Note that only one of the two arguments (pid or uuid) can be specified. If pid
- * is zero, uuid will be assumed to be a valid value; otherwise pid will be used.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns
- * an error code indicating the specific failure that occurred (in which
- * case the DNSServiceRef is not initialized). kDNSServiceErr_NotAuth is
- * returned to indicate that the calling process does not have entitlements
- * to use this API.
- */
-DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *sdRef, int32_t pid, uuid_t uuid);
-#endif
-
#ifdef __APPLE_API_PRIVATE
#define kDNSServiceCompPrivateDNS "PrivateDNS"
diff --git a/usr/src/lib/libdns_sd/common/dnssd_clientlib.c b/usr/src/lib/libdns_sd/common/dnssd_clientlib.c
index c22e54db61..649d403f02 100644
--- a/usr/src/lib/libdns_sd/common/dnssd_clientlib.c
+++ b/usr/src/lib/libdns_sd/common/dnssd_clientlib.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004-2011 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:
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
diff --git a/usr/src/lib/libdns_sd/common/dnssd_clientstub.c b/usr/src/lib/libdns_sd/common/dnssd_clientstub.c
index 6c44dae48d..b0fd9f9983 100644
--- a/usr/src/lib/libdns_sd/common/dnssd_clientstub.c
+++ b/usr/src/lib/libdns_sd/common/dnssd_clientstub.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003-2015 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:
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@@ -30,14 +30,15 @@
#include <stdlib.h>
#include <fcntl.h>
+#include "dnssd_ipc.h"
+
#if APPLE_OSX_mDNSResponder
#include <mach-o/dyld.h>
#include <uuid/uuid.h>
#include <TargetConditionals.h>
+#include "dns_sd_private.h"
#endif
-#include "dnssd_ipc.h"
-
#if defined(_WIN32)
#define _SSIZE_T
@@ -75,7 +76,7 @@ static void syslog( int priority, const char * message, ...)
va_start( args, message );
len = _vscprintf( message, args ) + 1;
buffer = malloc( len * sizeof(char) );
- if ( buffer ) { vsprintf( buffer, message, args ); OutputDebugString( buffer ); free( buffer ); }
+ if ( buffer ) { vsnprintf( buffer, len, message, args ); OutputDebugString( buffer ); free( buffer ); }
WSASetLastError( err );
}
#else
@@ -285,7 +286,7 @@ static int more_bytes(dnssd_sock_t sd)
// two ints and not just one.
int nfdbits = sizeof (int) * 8;
int nints = (sd/nfdbits) + 1;
- fs = (fd_set *)calloc(nints, sizeof(int));
+ fs = (fd_set *)calloc(nints, (size_t)sizeof(int));
if (fs == NULL)
{
syslog(LOG_WARNING, "dnssd_clientstub more_bytes: malloc failed");
@@ -356,7 +357,7 @@ static ipc_msg_hdr *create_hdr(uint32_t op, size_t *len, char **data_start, int
struct timeval tv;
if (gettimeofday(&tv, NULL) < 0)
{ syslog(LOG_WARNING, "dnssd_clientstub create_hdr: gettimeofday failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno)); return NULL; }
- sprintf(ctrl_path, "%s%d-%.3lx-%.6lu", CTL_PATH_PREFIX, (int)getpid(),
+ snprintf(ctrl_path, sizeof(ctrl_path), "%s%d-%.3lx-%.6lu", CTL_PATH_PREFIX, (int)getpid(),
(unsigned long)(tv.tv_sec & 0xFFF), (unsigned long)(tv.tv_usec));
*len += strlen(ctrl_path) + 1;
#else
@@ -406,7 +407,11 @@ static void FreeDNSServiceOp(DNSServiceOp *x)
// We don't use our DNSServiceRefValid macro here because if we're cleaning up after a socket() call failed
// then sockfd could legitimately contain a failing value (e.g. dnssd_InvalidSocket)
if ((x->sockfd ^ x->validator) != ValidatorBits)
+ {
+ static DNSServiceOp *op_were_not_going_to_free_but_we_need_to_fool_the_analyzer;
syslog(LOG_WARNING, "dnssd_clientstub attempt to dispose invalid DNSServiceRef %p %08X %08X", x, x->sockfd, x->validator);
+ op_were_not_going_to_free_but_we_need_to_fool_the_analyzer = x;
+ }
else
{
x->next = NULL;
@@ -531,6 +536,11 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
char* uds_serverpath = getenv(MDNS_UDS_SERVERPATH_ENVVAR);
if (uds_serverpath == NULL)
uds_serverpath = MDNS_UDS_SERVERPATH;
+ else if (strlen(uds_serverpath) >= MAX_CTLPATH)
+ {
+ uds_serverpath = MDNS_UDS_SERVERPATH;
+ syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: using default path since env len is invalid");
+ }
#endif
*ref = NULL;
sdr->sockfd = socket(AF_DNSSD, SOCK_STREAM, 0);
@@ -579,8 +589,10 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
}
else
{
+ #if !defined(USE_TCP_LOOPBACK)
syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: connect() failed path:%s Socket:%d Err:%d Errno:%d %s",
uds_serverpath, sdr->sockfd, err, dnssd_errno, dnssd_strerror(dnssd_errno));
+ #endif
dnssd_close(sdr->sockfd);
FreeDNSServiceOp(sdr);
return kDNSServiceErr_ServiceNotRunning;
@@ -598,21 +610,25 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
{
+ if (!hdr)
+ {
+ syslog(LOG_WARNING, "dnssd_clientstub deliver_request: !hdr");
+ return kDNSServiceErr_Unknown;
+ }
+
uint32_t datalen = hdr->datalen; // We take a copy here because we're going to convert hdr->datalen to network byte order
#if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
char *const data = (char *)hdr + sizeof(ipc_msg_hdr);
#endif
dnssd_sock_t listenfd = dnssd_InvalidSocket, errsd = dnssd_InvalidSocket;
DNSServiceErrorType err = kDNSServiceErr_Unknown; // Default for the "goto cleanup" cases
- int MakeSeparateReturnSocket = 0;
// Note: need to check hdr->op, not sdr->op.
// hdr->op contains the code for the specific operation we're currently doing, whereas sdr->op
// contains the original parent DNSServiceOp (e.g. for an add_record_request, hdr->op will be
// add_record_request but the parent sdr->op will be connection_request or reg_service_request)
- if (sdr->primary ||
- hdr->op == reg_record_request || hdr->op == add_record_request || hdr->op == update_record_request || hdr->op == remove_record_request)
- MakeSeparateReturnSocket = 1;
+ const int MakeSeparateReturnSocket = (sdr->primary ||
+ hdr->op == reg_record_request || hdr->op == add_record_request || hdr->op == update_record_request || hdr->op == remove_record_request);
if (!DNSServiceRefValid(sdr))
{
@@ -622,12 +638,6 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
return kDNSServiceErr_BadReference;
}
- if (!hdr)
- {
- syslog(LOG_WARNING, "dnssd_clientstub deliver_request: !hdr");
- return kDNSServiceErr_Unknown;
- }
-
if (MakeSeparateReturnSocket)
{
#if defined(USE_TCP_LOOPBACK)
@@ -637,21 +647,21 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
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");
- }
+ 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");
- }
+ 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
@@ -663,8 +673,8 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
dnssd_sockaddr_t caddr;
listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
if (!dnssd_SocketValid(listenfd)) {
- deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET socket");
- }
+ 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
@@ -676,19 +686,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 (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");
- }
+ 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");
- }
+ deliver_request_bailout("socketpair");
+ }
else
{
errsd = sp[0]; // We'll read our four-byte error code from sp[0]
@@ -756,7 +766,7 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
errsd = accept(listenfd, (struct sockaddr *)&daddr, &len);
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
@@ -1176,6 +1186,8 @@ DNSServiceErrorType DNSSD_API DNSServiceGetProperty(const char *property, void *
put_string(property, &ptr);
err = deliver_request(hdr, tmp); // Will free hdr for us
+ if (err) { DNSServiceRefDeallocate(tmp); return err; }
+
if (read_all(tmp->sockfd, (char*)&actualsize, (int)sizeof(actualsize)) < 0)
{ DNSServiceRefDeallocate(tmp); return kDNSServiceErr_ServiceNotRunning; }
@@ -1200,24 +1212,17 @@ DNSServiceErrorType DNSSD_API DNSServiceGetPID(const uint16_t srcport, int32_t *
size_t len = sizeof(int32_t);
DNSServiceErrorType err = ConnectToServer(&tmp, 0, getpid_request, NULL, NULL, NULL);
- if (err)
- return err;
+ if (err) return err;
hdr = create_hdr(getpid_request, &len, &ptr, 0, tmp);
- if (!hdr)
- {
- DNSServiceRefDeallocate(tmp);
- return kDNSServiceErr_NoMemory;
- }
+ if (!hdr) { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_NoMemory; }
put_uint16(srcport, &ptr);
err = deliver_request(hdr, tmp); // Will free hdr for us
+ if (err) { DNSServiceRefDeallocate(tmp); return err; }
if (read_all(tmp->sockfd, (char*)pid, sizeof(int32_t)) < 0)
- {
- DNSServiceRefDeallocate(tmp);
- return kDNSServiceErr_ServiceNotRunning;
- }
+ { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_ServiceNotRunning; }
DNSServiceRefDeallocate(tmp);
return kDNSServiceErr_NoError;
@@ -1399,16 +1404,17 @@ DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
static void handle_addrinfo_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
{
char hostname[kDNSServiceMaxDomainName];
- uint16_t rrtype, rdlen;
+ uint16_t rrtype, rrclass, rdlen;
const char *rdata;
uint32_t ttl;
get_string(&data, end, hostname, kDNSServiceMaxDomainName);
rrtype = get_uint16(&data, end);
- (void) get_uint16(&data, end); /* class is not used */
+ rrclass = get_uint16(&data, end);
rdlen = get_uint16(&data, end);
rdata = get_rdata (&data, end, rdlen);
ttl = get_uint32(&data, end);
+ (void)rrclass; // Unused
// We only generate client callbacks for A and AAAA results (including NXDOMAIN results for
// those types, if the client has requested those with the kDNSServiceFlagsReturnIntermediates).
@@ -1631,13 +1637,7 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister
hdr = create_hdr(reg_service_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
-
- // If it is going over a shared connection, then don't set the IPC_FLAGS_NOREPLY
- // as it affects all the operations over the shared connection. This is not
- // a normal case and hence receiving the response back from the daemon and
- // discarding it in ConnectionResponse is okay.
-
- if (!(flags & kDNSServiceFlagsShareConnection) && !callBack) hdr->ipc_flags |= IPC_FLAGS_NOREPLY;
+ if (!callBack) hdr->ipc_flags |= IPC_FLAGS_NOREPLY;
put_flags(flags, &ptr);
put_uint32(interfaceIndex, &ptr);
diff --git a/usr/src/lib/libdns_sd/common/dnssd_ipc.c b/usr/src/lib/libdns_sd/common/dnssd_ipc.c
index 6059eb392c..0fd75824f5 100644
--- a/usr/src/lib/libdns_sd/common/dnssd_ipc.c
+++ b/usr/src/lib/libdns_sd/common/dnssd_ipc.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003-2011 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:
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
diff --git a/usr/src/lib/libdns_sd/common/dnssd_ipc.h b/usr/src/lib/libdns_sd/common/dnssd_ipc.h
index ec098032b4..b9c0b144d3 100644
--- a/usr/src/lib/libdns_sd/common/dnssd_ipc.h
+++ b/usr/src/lib/libdns_sd/common/dnssd_ipc.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003-2015 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:
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@@ -88,7 +88,7 @@ extern char *win32_strerror(int inErrorCode);
# define MDNS_UDS_SERVERPATH_ENVVAR "DNSSD_UDS_PATH"
# define LISTENQ 100
// longest legal control path length
-# define MAX_CTLPATH 256
+# define MAX_CTLPATH (sizeof(((struct sockaddr_un*)0)->sun_path))
# define dnssd_sockaddr_t struct sockaddr_un
#endif