summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-19 08:52:21 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-20 11:23:32 +0200
commitf761b290f135957f47e1c9af71b4a81c76c32b48 (patch)
tree2b7d273db4ff2388867efec5ad432fa49cd4047e /mDNSResponder/mDNSMacOSX/mDNSMacOSX.c
parentmDNSResponder: Update to v576.30.4 (diff)
downloadrtems-libbsd-f761b290f135957f47e1c9af71b4a81c76c32b48.tar.bz2
mDNSResponder: Update to v625.41.2
The sources can be obtained via: https://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-625.41.2.tar.gz Update #3522.
Diffstat (limited to 'mDNSResponder/mDNSMacOSX/mDNSMacOSX.c')
-rw-r--r--mDNSResponder/mDNSMacOSX/mDNSMacOSX.c1136
1 files changed, 664 insertions, 472 deletions
diff --git a/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c b/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c
index f904c8b2..deae0d1a 100644
--- a/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c
+++ b/mDNSResponder/mDNSMacOSX/mDNSMacOSX.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.
@@ -61,7 +61,6 @@
#include <netinet/in_systm.h> // For n_long, required by <netinet/ip.h> below
#include <netinet/ip.h> // For IPTOS_LOWDELAY etc.
#include <netinet6/in6_var.h> // For IN6_IFF_NOTREADY etc.
-#include <netinet6/nd6.h> // For ND6_INFINITE_LIFETIME etc.
#include <netinet/tcp.h>
@@ -86,12 +85,20 @@
#include <asl.h>
#include <SystemConfiguration/SCPrivate.h>
+#if TARGET_OS_IPHONE
+// For WiFiManagerClientRef etc, declarations.
+#include <MobileGestalt.h>
+#include <MobileWiFi/WiFiManagerClient.h>
+#include <dlfcn.h>
+#endif // TARGET_OS_IPHONE
+
// Include definition of opaque_presence_indication for KEV_DL_NODE_PRESENCE handling logic.
#include <Kernel/IOKit/apple80211/apple80211_var.h>
#if APPLE_OSX_mDNSResponder
#include <DeviceToDeviceManager/DeviceToDeviceManager.h>
#include <AWACS.h>
+#include <ne_session.h> // for ne_session_set_socket_attributes()
#if !NO_D2D
D2DStatus D2DInitialize(CFRunLoopRef runLoop, D2DServiceCallback serviceCallback, void* userData) __attribute__((weak_import));
D2DStatus D2DRetain(D2DServiceInstance instanceHandle, D2DTransportType transportType) __attribute__((weak_import));
@@ -122,6 +129,8 @@ D2DStatus D2DTerminate() __attribute__((weak_import));
#define mDNS_IOREG_KA_KEY "mDNS_Keepalive"
#define mDNS_USER_CLIENT_CREATE_TYPE 'mDNS'
+#define DARK_WAKE_TIME 16 // Time we hold an idle sleep assertion for maintenance after a wake notification
+
// cache the InterfaceID of the AWDL interface
static mDNSInterfaceID AWDLInterfaceID;
@@ -213,9 +222,9 @@ mDNSexport void D2D_start_advertising_interface(NetworkInterfaceInfo *interface)
LogInfo("D2D_start_advertising_interface: %s", interface->ifname);
if (interface->RR_A.resrec.RecordType)
- external_start_advertising_service(&interface->RR_A.resrec, NULL);
+ external_start_advertising_service(&interface->RR_A.resrec, 0);
if (interface->RR_PTR.resrec.RecordType)
- external_start_advertising_service(&interface->RR_PTR.resrec, NULL);
+ external_start_advertising_service(&interface->RR_PTR.resrec, 0);
}
}
@@ -228,9 +237,9 @@ mDNSexport void D2D_stop_advertising_interface(NetworkInterfaceInfo *interface)
LogInfo("D2D_stop_advertising_interface: %s", interface->ifname);
if (interface->RR_A.resrec.RecordType)
- external_stop_advertising_service(&interface->RR_A.resrec, NULL);
+ external_stop_advertising_service(&interface->RR_A.resrec, 0);
if (interface->RR_PTR.resrec.RecordType)
- external_stop_advertising_service(&interface->RR_PTR.resrec, NULL);
+ external_stop_advertising_service(&interface->RR_PTR.resrec, 0);
}
}
@@ -960,8 +969,8 @@ mDNSexport void external_start_resolving_service(mDNSInterfaceID InterfaceID, co
if (AWDL_used && AWDLInterfaceID)
{
LogInfo("external_start_resolving_service: browse for TXT and SRV over AWDL");
- external_start_browsing_for_service(AWDLInterfaceID, fqdn, kDNSType_TXT, NULL);
- external_start_browsing_for_service(AWDLInterfaceID, fqdn, kDNSType_SRV, NULL);
+ external_start_browsing_for_service(AWDLInterfaceID, fqdn, kDNSType_TXT, 0);
+ external_start_browsing_for_service(AWDLInterfaceID, fqdn, kDNSType_SRV, 0);
}
}
@@ -1006,8 +1015,8 @@ mDNSexport void external_stop_resolving_service(mDNSInterfaceID InterfaceID, con
if (AWDL_used && AWDLInterfaceID)
{
LogInfo("external_stop_resolving_service: stop browse for TXT and SRV on AWDL");
- external_stop_browsing_for_service(AWDLInterfaceID, fqdn, kDNSType_TXT, NULL);
- external_stop_browsing_for_service(AWDLInterfaceID, fqdn, kDNSType_SRV, NULL);
+ external_stop_browsing_for_service(AWDLInterfaceID, fqdn, kDNSType_TXT, 0);
+ external_stop_browsing_for_service(AWDLInterfaceID, fqdn, kDNSType_SRV, 0);
}
}
@@ -1037,22 +1046,17 @@ mDNSexport void external_stop_resolving_service(const domainname *const fqdn, DN
// to run up the user's bill sending multicast traffic over a link where there's only a single device at the
// other end, and that device (e.g. a modem bank) is probably not answering Multicast DNS queries anyway.
-// We also don't want to use multicast on *any* interface on very constrained devices.
-#if TARGET_OS_NANO
-#define MulticastInterface(i) (mDNSfalse)
+// We also don't want to use multicast on *any* physical interface on very constrained devices.
+#if 0
+#define MulticastInterface(i) ((i)->ifa_flags & IFF_LOOPBACK)
+#elif TARGET_OS_WATCH
+#define MulticastInterface(i) ((i)->m->NumAllInterfaceRecords + (i)->m->NumAllInterfaceQuestions > 0 && ((i)->ifa_flags & IFF_MULTICAST) && !((i)->ifa_flags & IFF_POINTOPOINT))
#else
#define MulticastInterface(i) (((i)->ifa_flags & IFF_MULTICAST) && !((i)->ifa_flags & IFF_POINTOPOINT))
#endif
mDNSexport void NotifyOfElusiveBug(const char *title, const char *msg) // Both strings are UTF-8 text
{
- static int notifyCount = 0;
- if (notifyCount) return;
-
- // If we display our alert early in the boot process, then it vanishes once the desktop appears.
- // To avoid this, we don't try to display alerts in the first three minutes after boot.
- if ((mDNSu32)(mDNSPlatformRawTime()) < (mDNSu32)(mDNSPlatformOneSecond * 180)) return;
-
// Unless ForceAlerts is defined, we only show these bug report alerts on machines that have a 17.x.x.x address
#if !ForceAlerts
{
@@ -1065,16 +1069,54 @@ mDNSexport void NotifyOfElusiveBug(const char *title, const char *msg) // Both
}
#endif
- LogMsg("%s", title);
- LogMsg("%s", msg);
- // Display a notification to the user
- notifyCount++;
+ LogMsg("NotifyOfElusiveBug: %s", title);
+ LogMsg("NotifyOfElusiveBug: %s", msg);
+
+ // If we display our alert early in the boot process, then it vanishes once the desktop appears.
+ // To avoid this, we don't try to display alerts in the first three minutes after boot.
+ if ((mDNSu32)(mDNSPlatformRawTime()) < (mDNSu32)(mDNSPlatformOneSecond * 180))
+ { LogMsg("Suppressing notification early in boot: %d", mDNSPlatformRawTime()); return; }
#ifndef NO_CFUSERNOTIFICATION
- mDNSNotify(title, msg);
+ static int notifyCount = 0; // To guard against excessive display of warning notifications
+ if (notifyCount < 5) { notifyCount++; mDNSNotify(title, msg); }
#endif /* NO_CFUSERNOTIFICATION */
}
+// Write a syslog message and display an alert, then if ForceAlerts is set, generate a stack trace
+#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
+mDNSexport void LogMemCorruption(const char *format, ...)
+{
+ char buffer[512];
+ va_list ptr;
+ va_start(ptr,format);
+ buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
+ va_end(ptr);
+ LogMsg("!!!! %s !!!!", buffer);
+ NotifyOfElusiveBug("Memory Corruption", buffer);
+#if ForceAlerts
+ *(volatile long*)0 = 0; // Trick to crash and get a stack trace right here, if that's what we want
+#endif
+}
+#endif
+
+// Like LogMemCorruption above, but only display the alert if ForceAlerts is set and we're going to generate a stack trace
+#if APPLE_OSX_mDNSResponder
+mDNSexport void LogFatalError(const char *format, ...)
+{
+ char buffer[512];
+ va_list ptr;
+ va_start(ptr,format);
+ buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
+ va_end(ptr);
+ LogMsg("!!!! %s !!!!", buffer);
+#if ForceAlerts
+ NotifyOfElusiveBug("Fatal Error. See /Library/Logs/DiagnosticReports", buffer);
+ *(volatile long*)0 = 0; // Trick to crash and get a stack trace right here, if that's what we want
+#endif
+}
+#endif
+
// Returns true if it is an AppleTV based hardware running iOS, false otherwise
mDNSlocal mDNSBool IsAppleTV(void)
{
@@ -1121,7 +1163,6 @@ mDNSlocal void DynamicStoreWrite(int key, const char* subkey, uintptr_t value, s
Boolean release_sckey = FALSE;
CFDataRef bytes = NULL;
CFPropertyListRef plist = NULL;
- SCDynamicStoreRef store = NULL;
switch ((enum mDNSDynamicStoreSetConfigKey)key)
{
@@ -1161,29 +1202,20 @@ mDNSlocal void DynamicStoreWrite(int key, const char* subkey, uintptr_t value, s
LogMsg("CFDataCreateWithBytesNoCopy of value failed");
goto fin;
}
- if (NULL == (plist = CFPropertyListCreateFromXMLData(NULL, bytes,
- kCFPropertyListImmutable, NULL)))
+ if (NULL == (plist = CFPropertyListCreateWithData(NULL, bytes, kCFPropertyListImmutable, NULL, NULL)))
{
- LogMsg("CFPropertyListCreateFromXMLData of bytes failed");
+ LogMsg("CFPropertyListCreateWithData of bytes failed");
goto fin;
}
CFRelease(bytes);
bytes = NULL;
- if (NULL == (store = SCDynamicStoreCreate(NULL,
- CFSTR(kmDNSResponderServName), NULL, NULL)))
- {
- LogMsg("SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
- goto fin;
- }
- SCDynamicStoreSetValue(store, sckey, plist);
+ SCDynamicStoreSetValue(NULL, sckey, plist);
fin:
if (NULL != bytes)
CFRelease(bytes);
if (NULL != plist)
CFRelease(plist);
- if (NULL != store)
- CFRelease(store);
if (release_sckey && sckey)
CFRelease(sckey);
}
@@ -1210,6 +1242,7 @@ mDNSexport void mDNSDynamicStoreSetConfig(int key, const char *subkey, CFPropert
if (!subkeyCopy)
{
LogMsg("mDNSDynamicStoreSetConfig: ERROR subkeyCopy NULL");
+ CFRelease(valueCopy);
return;
}
mDNSPlatformMemCopy(subkeyCopy, subkey, len);
@@ -1219,7 +1252,6 @@ mDNSexport void mDNSDynamicStoreSetConfig(int key, const char *subkey, CFPropert
dispatch_async(DynamicStoreQueue, ^{
CFWriteStreamRef stream = NULL;
CFDataRef bytes = NULL;
- CFStringRef error;
CFIndex ret;
if (NULL == (stream = CFWriteStreamCreateWithAllocatedBuffers(NULL, NULL)))
@@ -1228,7 +1260,7 @@ mDNSexport void mDNSDynamicStoreSetConfig(int key, const char *subkey, CFPropert
goto END;
}
CFWriteStreamOpen(stream);
- ret = CFPropertyListWriteToStream(valueCopy, stream, kCFPropertyListBinaryFormat_v1_0, &error);
+ ret = CFPropertyListWrite(valueCopy, stream, kCFPropertyListBinaryFormat_v1_0, 0, NULL);
if (ret == 0)
{
LogMsg("mDNSDynamicStoreSetConfig : CFPropertyListWriteToStream failed (Could not write property list to stream)");
@@ -1298,8 +1330,6 @@ mDNSlocal mDNSBool GetmDNSManagedPrefKeyVal(SCPreferencesRef prefs, CFStringRef
LogMsg("GetmDNSManagedPrefKeyVal: mDNSManagedPrefs are NULL!");
val = mDNSfalse;
}
- if (val_cf)
- CFRelease(val_cf);
return (val);
}
@@ -1702,6 +1732,8 @@ mDNSexport void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst,
if (src)
{
int s;
+ char unenc_name[MAX_ESCAPED_DOMAIN_NAME];
+ ConvertDomainNameToCString(&q->qname, unenc_name);
if (dst->type == mDNSAddrType_IPv4)
s = src->ss.sktv4;
@@ -1719,6 +1751,10 @@ mDNSexport void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst,
LogInfo("mDNSPlatformSetuDNSSocktOpt: Delegate UUID failed %s", strerror(errno));
}
+ // set the domain on the UDP socket
+ if (!(ne_session_set_socket_attributes(s, unenc_name, NULL)))
+ LogInfo("mDNSPlatformSetuDNSSocktOpt: ne_session_set_socket_attributes()-> setting domain failed for %s", unenc_name);
+
#if defined(SO_NOWAKEFROMSLEEP)
int nowake = 1;
if (setsockopt(s, SOL_SOCKET, SO_NOWAKEFROMSLEEP, &nowake, sizeof(nowake)) == -1)
@@ -1818,14 +1854,14 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms
{
if (errno != ENOPROTOOPT) LogInfo("mDNSPlatformSendUDP: setsockopt: IP_MUTLTICAST_IFINDEX returned %d", errno);
err = setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &info->ifa_v4addr, sizeof(info->ifa_v4addr));
- if (err < 0 && !m->p->NetworkChanged)
+ if (err < 0 && !m->NetworkChanged)
LogMsg("setsockopt - IP_MULTICAST_IF error %.4a %d errno %d (%s)", &info->ifa_v4addr, err, errno, strerror(errno));
}
}
#else
{
err = setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &info->ifa_v4addr, sizeof(info->ifa_v4addr));
- if (err < 0 && !m->p->NetworkChanged)
+ if (err < 0 && !m->NetworkChanged)
LogMsg("setsockopt - IP_MULTICAST_IF error %.4a %d errno %d (%s)", &info->ifa_v4addr, err, errno, strerror(errno));
}
@@ -1855,14 +1891,23 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms
LogInfo("setsockopt - IPV6_MUTLICAST_IF scopeid %d, not a valid interface", info->scope_id);
}
}
+#ifdef IPV6_BOUND_IF
+ if (info) // Specify outgoing interface for non-multicast destination
+ {
+ if (!mDNSAddrIsDNSMulticast(dst))
+ {
+ if (info->scope_id == 0)
+ LogInfo("IPV6_BOUND_IF socket option not set -- info %p (%s) scope_id is zero", info, ifa_name);
+ else
+ setsockopt(s, IPPROTO_IPV6, IPV6_BOUND_IF, &info->scope_id, sizeof(info->scope_id));
+ }
+ }
+#endif
}
else
{
- LogMsg("mDNSPlatformSendUDP: dst is not an IPv4 or IPv6 address!");
-#if ForceAlerts
- *(long*)0 = 0;
-#endif
+ LogFatalError("mDNSPlatformSendUDP: dst is not an IPv4 or IPv6 address!");
return mStatus_BadParamErr;
}
@@ -1899,7 +1944,7 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms
// but this means that sometimes it starts before configd has finished setting up the multicast routing entries.
if (errno == EHOSTUNREACH && (mDNSu32)(mDNSPlatformRawTime()) < (mDNSu32)(mDNSPlatformOneSecond * 180)) return(mStatus_TransientErr);
// Don't report EADDRNOTAVAIL ("Can't assign requested address") if we're in the middle of a network configuration change
- if (errno == EADDRNOTAVAIL && m->p->NetworkChanged) return(mStatus_TransientErr);
+ if (errno == EADDRNOTAVAIL && m->NetworkChanged) return(mStatus_TransientErr);
if (errno == EHOSTUNREACH || errno == EADDRNOTAVAIL || errno == ENETDOWN)
LogInfo("mDNSPlatformSendUDP sendto(%d) failed to send packet on InterfaceID %p %5s/%d to %#a:%d skt %d error %d errno %d (%s) %lu",
s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, errno, strerror(errno), (mDNSu32)(m->timenow));
@@ -2006,6 +2051,7 @@ mDNSexport ssize_t myrecvfrom(const int s, void *const buffer, const size_t max,
return(n);
}
+// What is this for, and why does it use xor instead of a simple quality check? -- SC
mDNSlocal mDNSInterfaceID FindMyInterface(mDNS *const m, const mDNSAddr *addr)
{
NetworkInterfaceInfo *intf;
@@ -2043,6 +2089,12 @@ mDNSlocal mDNSInterfaceID FindMyInterface(mDNS *const m, const mDNSAddr *addr)
return(mDNSInterface_Any);
}
+// 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
mDNSexport mDNSBool mDNSPlatformPeekUDP(mDNS *const m, UDPSocket *src)
{
// We should have a DNSMessage header followed by the question and an answer
@@ -2165,6 +2217,15 @@ mDNSexport void myKQSocketCallBack(int s1, short filter, void *context)
if (!closed) ss->closeFlag = mDNSNULL;
}
+ // If a client application is put in the background, it's socket to us can go defunct and
+ // we'll get an ENOTCONN error on that connection. Just close the socket in that case.
+ if (err < 0 && errno == ENOTCONN)
+ {
+ LogInfo("myKQSocketCallBack: ENOTCONN, closing socket");
+ close(s1);
+ return;
+ }
+
if (err < 0 && (errno != EWOULDBLOCK || count == 0))
{
// Something is busted here.
@@ -3057,7 +3118,7 @@ mDNSlocal mStatus SetupSocket(KQSocketSet *cp, const mDNSIPPort port, u_short sa
// We want to receive packet TTL value so we can check it
err = setsockopt(skt, IPPROTO_IP, IP_RECVTTL, &on, sizeof(on));
- // We ignore errors here -- we already know Jaguar doesn't support this, but we can get by without it
+ if (err < 0) { errstr = "setsockopt - IP_RECVTTL"; goto fail; }
// Send unicast packets with TTL 255
err = setsockopt(skt, IPPROTO_IP, IP_TTL, &twofivefive, sizeof(twofivefive));
@@ -3139,7 +3200,7 @@ mDNSlocal mStatus SetupSocket(KQSocketSet *cp, const mDNSIPPort port, u_short sa
#endif
KQueueSet(*s, EV_ADD, EVFILT_READ, k);
- return(err);
+ return(mStatus_NoError);
fail:
// For "bind" failures, only write log messages for our shared mDNS port, or for binding to zero
@@ -3247,7 +3308,7 @@ mDNSexport void mDNSPlatformSetLocalAddressCacheEntry(mDNS *const m, const mDNSA
if (info == NULL) { LogMsg("mDNSPlatformSetLocalAddressCacheEntry: Invalid interface index %p", InterfaceID); return; }
// Manually inject an entry into our local ARP cache.
// (We can't do this by sending an ARP broadcast, because the kernel only pays attention to incoming ARP packets, not outgoing.)
- if (!mDNS_AddressIsLocalSubnet(m, InterfaceID, tpa, mDNSNULL))
+ if (!mDNS_AddressIsLocalSubnet(m, InterfaceID, tpa))
LogSPS("Don't need address cache entry for %s %#a %.6a", info->ifinfo.ifname, tpa, tha);
else
{
@@ -3348,20 +3409,16 @@ mDNSexport void mDNSPlatformSendKeepalive(mDNSAddr *sadd, mDNSAddr *dadd, mDNSIP
mDNSexport mStatus mDNSPlatformClearSPSMACAddr(void)
{
- SCDynamicStoreRef store = NULL;
CFStringRef entityname = NULL;
- if ((store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:ClearSPSMACAddress"), NULL, NULL)))
+ if ((entityname = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s%s%s"), "State:/Network/Interface/", "[^/]", "/BonjourSleepProxyAddress")))
{
- if ((entityname = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s%s%s"), "State:/Network/Interface/", "[^/]", "/BonjourSleepProxyAddress")))
- {
- if (SCDynamicStoreRemoveValue(store, entityname) == false)
- LogMsg("mDNSPlatformClearSPSMACAddr: Unable to remove key");
- }
+ if (SCDynamicStoreRemoveValue(NULL, entityname) == false)
+ LogSPS("mDNSPlatformClearSPSMACAddr: Unable to remove key");
}
- if (entityname) CFRelease(entityname);
- if (store) CFRelease(store);
+ if (entityname)
+ CFRelease(entityname);
return KERN_SUCCESS;
}
@@ -3578,7 +3635,7 @@ mDNSexport void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID
LogSPS("mDNSPlatformUpdateProxyList: No need for filter");
if (m->timenow == 0) LogMsg("mDNSPlatformUpdateProxyList: m->timenow == 0");
// Schedule check to see if we can close this BPF_fd now
- if (!m->p->NetworkChanged) m->p->NetworkChanged = NonZeroTime(m->timenow + mDNSPlatformOneSecond * 2);
+ if (!m->NetworkChanged) m->NetworkChanged = NonZeroTime(m->timenow + mDNSPlatformOneSecond * 2);
// prog.bf_len = 0; This seems to panic the kernel
if (x->BPF_fd < 0) return; // If we've already closed our BPF_fd, no need to generate an error message below
}
@@ -3671,46 +3728,48 @@ mDNSexport void mDNSPlatformReceiveBPF_fd(mDNS *const m, int fd)
#endif
#ifndef NO_SECURITYFRAMEWORK
-mDNSlocal CFArrayRef GetCertChain(SecIdentityRef identity)
+mDNSlocal CFArrayRef CopyCertChain(SecIdentityRef identity)
{
CFMutableArrayRef certChain = NULL;
- if (!identity) { LogMsg("getCertChain: identity is NULL"); return(NULL); }
+ if (!identity) { LogMsg("CopyCertChain: identity is NULL"); return(NULL); }
SecCertificateRef cert;
OSStatus err = SecIdentityCopyCertificate(identity, &cert);
- if (err || !cert) LogMsg("getCertChain: SecIdentityCopyCertificate() returned %d", (int) err);
+ if (err || !cert) LogMsg("CopyCertChain: SecIdentityCopyCertificate() returned %d", (int) err);
else
{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SecPolicySearchRef searchRef;
err = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &searchRef);
- if (err || !searchRef) LogMsg("getCertChain: SecPolicySearchCreate() returned %d", (int) err);
+ if (err || !searchRef) LogMsg("CopyCertChain: SecPolicySearchCreate() returned %d", (int) err);
else
{
SecPolicyRef policy;
err = SecPolicySearchCopyNext(searchRef, &policy);
- if (err || !policy) LogMsg("getCertChain: SecPolicySearchCopyNext() returned %d", (int) err);
+ if (err || !policy) LogMsg("CopyCertChain: SecPolicySearchCopyNext() returned %d", (int) err);
else
{
CFArrayRef wrappedCert = CFArrayCreate(NULL, (const void**) &cert, 1, &kCFTypeArrayCallBacks);
- if (!wrappedCert) LogMsg("getCertChain: wrappedCert is NULL");
+ if (!wrappedCert) LogMsg("CopyCertChain: wrappedCert is NULL");
else
{
SecTrustRef trust;
err = SecTrustCreateWithCertificates(wrappedCert, policy, &trust);
- if (err || !trust) LogMsg("getCertChain: SecTrustCreateWithCertificates() returned %d", (int) err);
+ if (err || !trust) LogMsg("CopyCertChain: SecTrustCreateWithCertificates() returned %d", (int) err);
else
{
err = SecTrustEvaluate(trust, NULL);
- if (err) LogMsg("getCertChain: SecTrustEvaluate() returned %d", (int) err);
+ if (err) LogMsg("CopyCertChain: SecTrustEvaluate() returned %d", (int) err);
else
{
CFArrayRef rawCertChain;
CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
err = SecTrustGetResult(trust, NULL, &rawCertChain, &statusChain);
- if (err || !rawCertChain || !statusChain) LogMsg("getCertChain: SecTrustGetResult() returned %d", (int) err);
+ if (err || !rawCertChain || !statusChain) LogMsg("CopyCertChain: SecTrustGetResult() returned %d", (int) err);
else
{
certChain = CFArrayCreateMutableCopy(NULL, 0, rawCertChain);
- if (!certChain) LogMsg("getCertChain: certChain is NULL");
+ if (!certChain) LogMsg("CopyCertChain: certChain is NULL");
else
{
// Replace the SecCertificateRef at certChain[0] with a SecIdentityRef per documentation for SSLSetCertificate:
@@ -3734,6 +3793,7 @@ mDNSlocal CFArrayRef GetCertChain(SecIdentityRef identity)
}
CFRelease(searchRef);
}
+#pragma clang diagnostic pop
CFRelease(cert);
}
return certChain;
@@ -3749,6 +3809,8 @@ mDNSexport mStatus mDNSPlatformTLSSetupCerts(void)
SecIdentitySearchRef srchRef = nil;
OSStatus err;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
// search for "any" identity matching specified key use
// In this app, we expect there to be exactly one
err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_DECRYPT, &srchRef);
@@ -3756,13 +3818,14 @@ mDNSexport mStatus mDNSPlatformTLSSetupCerts(void)
err = SecIdentitySearchCopyNext(srchRef, &identity);
if (err) { LogMsg("ERROR: mDNSPlatformTLSSetupCerts: SecIdentitySearchCopyNext returned %d", (int) err); return err; }
+#pragma clang diagnostic pop
if (CFGetTypeID(identity) != SecIdentityGetTypeID())
{ LogMsg("ERROR: mDNSPlatformTLSSetupCerts: SecIdentitySearchCopyNext CFTypeID failure"); return mStatus_UnknownErr; }
- // Found one. Call getCertChain to create the correct certificate chain.
- ServerCerts = GetCertChain(identity);
- if (ServerCerts == nil) { LogMsg("ERROR: mDNSPlatformTLSSetupCerts: getCertChain error"); return mStatus_UnknownErr; }
+ // Found one. Call CopyCertChain to create the correct certificate chain.
+ ServerCerts = CopyCertChain(identity);
+ if (ServerCerts == nil) { LogMsg("ERROR: mDNSPlatformTLSSetupCerts: CopyCertChain error"); return mStatus_UnknownErr; }
return mStatus_NoError;
#endif /* NO_SECURITYFRAMEWORK */
@@ -3841,26 +3904,22 @@ mDNSlocal mStatus SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa)
mDNSlocal mDNSEthAddr GetBSSID(char *ifa_name)
{
mDNSEthAddr eth = zeroEthAddr;
- SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:GetBSSID"), NULL, NULL);
- if (!store)
- LogMsg("GetBSSID: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
- else
+
+ CFStringRef entityname = CFStringCreateWithFormat(NULL, NULL, CFSTR("State:/Network/Interface/%s/AirPort"), ifa_name);
+ if (entityname)
{
- CFStringRef entityname = CFStringCreateWithFormat(NULL, NULL, CFSTR("State:/Network/Interface/%s/AirPort"), ifa_name);
- if (entityname)
+ CFDictionaryRef dict = SCDynamicStoreCopyValue(NULL, entityname);
+ if (dict)
{
- CFDictionaryRef dict = SCDynamicStoreCopyValue(store, entityname);
- if (dict)
- {
- CFRange range = { 0, 6 }; // Offset, length
- CFDataRef data = CFDictionaryGetValue(dict, CFSTR("BSSID"));
- if (data && CFDataGetLength(data) == 6) CFDataGetBytes(data, range, eth.b);
- CFRelease(dict);
- }
- CFRelease(entityname);
+ CFRange range = { 0, 6 }; // Offset, length
+ CFDataRef data = CFDictionaryGetValue(dict, CFSTR("BSSID"));
+ if (data && CFDataGetLength(data) == 6)
+ CFDataGetBytes(data, range, eth.b);
+ CFRelease(dict);
}
- CFRelease(store);
+ CFRelease(entityname);
}
+
return(eth);
}
@@ -4005,6 +4064,134 @@ mDNSlocal u_int64_t getExtendedFlags(char * ifa_name)
return ifr.ifr_eflags;
}
+#if TARGET_OS_IPHONE
+
+// Function pointers for the routines we use in the MobileWiFi framework.
+static WiFiManagerClientRef (*WiFiManagerClientCreate_p)(CFAllocatorRef allocator, WiFiClientType type) = mDNSNULL;
+static CFArrayRef (*WiFiManagerClientCopyDevices_p)(WiFiManagerClientRef manager) = mDNSNULL;
+static WiFiNetworkRef (*WiFiDeviceClientCopyCurrentNetwork_p)(WiFiDeviceClientRef device) = mDNSNULL;
+static bool (*WiFiNetworkIsCarPlay_p)(WiFiNetworkRef network) = mDNSNULL;
+
+mDNSlocal mDNSBool MobileWiFiLibLoad(void)
+{
+ static mDNSBool isInitialized = mDNSfalse;
+ static void *MobileWiFiLib_p = mDNSNULL;
+ static const char path[] = "/System/Library/PrivateFrameworks/MobileWiFi.framework/MobileWiFi";
+
+ if (!isInitialized)
+ {
+ if (!MobileWiFiLib_p)
+ {
+ MobileWiFiLib_p = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
+ if (!MobileWiFiLib_p)
+ {
+ LogInfo("MobileWiFiLibLoad: dlopen() failed.");
+ goto exit;
+ }
+ }
+
+ if (!WiFiManagerClientCreate_p)
+ {
+ WiFiManagerClientCreate_p = dlsym(MobileWiFiLib_p, "WiFiManagerClientCreate");
+ if (!WiFiManagerClientCreate_p)
+ {
+ LogInfo("MobileWiFiLibLoad: load of WiFiManagerClientCreate symbol failed.");
+ goto exit;
+ }
+ }
+
+ if (!WiFiManagerClientCopyDevices_p)
+ {
+ WiFiManagerClientCopyDevices_p = dlsym(MobileWiFiLib_p, "WiFiManagerClientCopyDevices");
+ if (!WiFiManagerClientCopyDevices_p)
+ {
+ LogInfo("MobileWiFiLibLoad: load of WiFiManagerClientCopyDevices symbol failed.");
+ goto exit;
+ }
+ }
+
+ if (!WiFiDeviceClientCopyCurrentNetwork_p)
+ {
+ WiFiDeviceClientCopyCurrentNetwork_p = dlsym(MobileWiFiLib_p, "WiFiDeviceClientCopyCurrentNetwork");
+ if (!WiFiDeviceClientCopyCurrentNetwork_p)
+ {
+ LogInfo("MobileWiFiLibLoad: load of WiFiDeviceClientCopyCurrentNetwork symbol failed.");
+ goto exit;
+ }
+ }
+
+ if (!WiFiNetworkIsCarPlay_p)
+ {
+ WiFiNetworkIsCarPlay_p = dlsym(MobileWiFiLib_p, "WiFiNetworkIsCarPlay");
+ if (!WiFiNetworkIsCarPlay_p)
+ {
+ LogInfo("MobileWiFiLibLoad: load of WiFiNetworkIsCarPlay symbol failed.");
+ goto exit;
+ }
+ }
+
+ isInitialized = mDNStrue;
+ }
+
+exit:
+ return isInitialized;
+}
+
+// Return true if the interface is associate to a CarPlay hosted SSID.
+mDNSlocal mDNSBool IsCarPlaySSID(char *ifa_name)
+{
+ mDNSBool rvalue = mDNSfalse;
+
+ if (!MobileWiFiLibLoad())
+ return mDNSfalse;
+
+ // If we have associated with a CarPlay hosted SSID, then use the same
+ // optimizations that are used if an interface has the IFEF_DIRECTLINK flag set.
+
+ WiFiManagerClientRef manager;
+
+ manager = WiFiManagerClientCreate_p(NULL, kWiFiClientTypeNormal);
+ if (manager != NULL)
+ {
+ CFArrayRef devices;
+
+ devices = WiFiManagerClientCopyDevices_p(manager);
+ if (devices != NULL)
+ {
+ WiFiDeviceClientRef device;
+ WiFiNetworkRef network;
+
+ device = (WiFiDeviceClientRef)CFArrayGetValueAtIndex(devices, 0);
+ network = WiFiDeviceClientCopyCurrentNetwork_p(device);
+ if (network != NULL)
+ {
+ if (WiFiNetworkIsCarPlay_p(network))
+ {
+ LogInfo("%s is CarPlay hosted", ifa_name);
+ rvalue = mDNStrue;
+ }
+ CFRelease(network);
+ }
+ CFRelease(devices);
+ }
+ CFRelease(manager);
+ }
+
+ return rvalue;
+}
+
+#else // TARGET_OS_IPHONE
+
+mDNSlocal mDNSBool IsCarPlaySSID(char *ifa_name)
+{
+ (void)ifa_name; // unused
+
+ // OSX WifiManager currently does not implement WiFiNetworkIsCarPlay()
+ return mDNSfalse;;
+}
+
+#endif // TARGET_OS_IPHONE
+
// Returns pointer to newly created NetworkInterfaceInfoOSX object, or
// pointer to already-existing NetworkInterfaceInfoOSX object found in list, or
// may return NULL if out of memory (unlikely) or parameters are invalid for some reason
@@ -4050,7 +4237,7 @@ mDNSlocal NetworkInterfaceInfoOSX *AddInterfaceToList(mDNS *const m, struct ifad
{
mDNS_Lock(m);
if (NetWake) mDNS_ActivateNetWake_internal (m, &(*p)->ifinfo);
- else mDNS_DeactivateNetWake_internal(m, &(*p)->ifinfo);
+ else mDNS_DeactivateNetWake_internal(m, &(*p)->ifinfo);
mDNS_Unlock(m);
}
}
@@ -4075,7 +4262,11 @@ mDNSlocal NetworkInterfaceInfoOSX *AddInterfaceToList(mDNS *const m, struct ifad
i->ifinfo.McastTxRx = mDNSfalse; // For now; will be set up later at the end of UpdateInterfaceList
i->ifinfo.Loopback = ((ifa->ifa_flags & IFF_LOOPBACK) != 0) ? mDNStrue : mDNSfalse;
i->ifinfo.IgnoreIPv4LL = ((eflags & IFEF_ARPLL) != 0) ? mDNSfalse : mDNStrue;
- i->ifinfo.DirectLink = (eflags & IFEF_DIRECTLINK) ? mDNStrue: mDNSfalse;
+
+ if (eflags & IFEF_DIRECTLINK)
+ i->ifinfo.DirectLink = mDNStrue;
+ else
+ i->ifinfo.DirectLink = IsCarPlaySSID(ifa->ifa_name);
i->next = mDNSNULL;
i->m = m;
@@ -4085,9 +4276,17 @@ mDNSlocal NetworkInterfaceInfoOSX *AddInterfaceToList(mDNS *const m, struct ifad
i->D2DInterface = (eflags & IFEF_LOCALNET_PRIVATE) ? mDNStrue: mDNSfalse;
if (eflags & IFEF_AWDL)
{
+ // Set SupportsUnicastMDNSResponse false for the AWDL interface since unicast reserves
+ // limited AWDL resources so we don't set the kDNSQClass_UnicastResponse bit in
+ // Bonjour requests over the AWDL interface.
+ i->ifinfo.SupportsUnicastMDNSResponse = mDNSfalse;
AWDLInterfaceID = i->ifinfo.InterfaceID;
LogInfo("AddInterfaceToList: AWDLInterfaceID = %d", (int) AWDLInterfaceID);
}
+ else
+ {
+ i->ifinfo.SupportsUnicastMDNSResponse = mDNStrue;
+ }
i->AppearanceTime = utc; // Brand new interface; AppearanceTime is now
i->LastSeen = utc;
i->ifa_flags = ifa->ifa_flags;
@@ -4100,7 +4299,7 @@ mDNSlocal NetworkInterfaceInfoOSX *AddInterfaceToList(mDNS *const m, struct ifad
i->Registered = mDNSNULL;
// Do this AFTER i->BSSID has been set up
- i->ifinfo.NetWake = NetWakeInterface(i);
+ i->ifinfo.NetWake = (eflags & IFEF_EXPENSIVE)? mDNSfalse : NetWakeInterface(i);
GetMAC(&i->ifinfo.MAC, scope_id);
if (i->ifinfo.NetWake && !i->ifinfo.MAC.l[0])
LogMsg("AddInterfaceToList: Bad MAC address %.6a for %d %s %#a", &i->ifinfo.MAC, scope_id, i->ifinfo.ifname, &ip);
@@ -4203,7 +4402,6 @@ mDNSlocal void UpdateAutoTunnelDomainStatus(const mDNS *const m, const DomainAut
const NATTraversalInfo *const llq = m->LLQNAT.clientCallback ? &m->LLQNAT : mDNSNULL;
const NATTraversalInfo *const tun = m->AutoTunnelNAT.clientContext ? &m->AutoTunnelNAT : mDNSNULL;
char buffer[1024];
- mDNSu32 buflen = 0;
CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFStringRef domain = NULL;
CFStringRef tmp = NULL;
@@ -4222,7 +4420,7 @@ mDNSlocal void UpdateAutoTunnelDomainStatus(const mDNS *const m, const DomainAut
if (!dict) { LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFDictionary dict"); return; }
- buflen = mDNS_snprintf(buffer, sizeof(buffer), "%##s", info->domain.c);
+ mDNS_snprintf(buffer, sizeof(buffer), "%##s", info->domain.c);
domain = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
if (!domain) { LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString domain"); return; }
@@ -5204,6 +5402,7 @@ mDNSexport void AddNewClientTunnel(mDNS *const m, DNSQuestion *const q)
p->q.qnameOrig = mDNSNULL;
p->q.AnonInfo = mDNSNULL;
p->q.pid = mDNSPlatformGetPID();
+ p->q.euid = 0;
p->q.QuestionCallback = AutoTunnelCallback;
p->q.QuestionContext = p;
@@ -5222,7 +5421,7 @@ mDNSlocal mStatus UpdateInterfaceList(mDNS *const m, mDNSs32 utc)
{
mDNSBool foundav4 = mDNSfalse;
mDNSBool foundav6 = mDNSfalse;
- struct ifaddrs *ifa = myGetIfAddrs(1);
+ struct ifaddrs *ifa = myGetIfAddrs(0);
struct ifaddrs *v4Loopback = NULL;
struct ifaddrs *v6Loopback = NULL;
char defaultname[64];
@@ -5402,14 +5601,14 @@ mDNSlocal mStatus UpdateInterfaceList(mDNS *const m, mDNSs32 utc)
namechange = mDNStrue;
}
-#if APPLE_OSX_mDNSResponder
if (namechange) // If either name has changed, we need to tickle our AutoTunnel state machine to update its registered records
{
+#if APPLE_OSX_mDNSResponder
DomainAuthInfo *info;
for (info = m->AuthInfoList; info; info = info->next)
if (info->AutoTunnel) AutoTunnelHostNameChanged(m, info);
- }
#endif // APPLE_OSX_mDNSResponder
+ }
return(mStatus_NoError);
}
@@ -5430,7 +5629,7 @@ mDNSlocal int CountMaskBits(mDNSAddr *mask)
return(bits);
}
-// returns count of non-link local V4 addresses registered
+// Returns count of non-link local V4 addresses registered (why? -- SC)
mDNSlocal int SetupActiveInterfaces(mDNS *const m, mDNSs32 utc)
{
NetworkInterfaceInfoOSX *i;
@@ -5452,9 +5651,7 @@ mDNSlocal int SetupActiveInterfaces(mDNS *const m, mDNSs32 utc)
{
// Note: If i->Registered is set, that means we've called mDNS_RegisterInterface() for this interface,
// so we need to make sure we call mDNS_DeregisterInterface() before disposing it.
- // If i->Registered is NOT set, then we haven't registered it and we should not try to deregister it
- //
-
+ // If i->Registered is NOT set, then we haven't registered it and we should not try to deregister it.
i->Registered = primary;
// If i->LastSeen == utc, then this is a brand-new interface, just created, or an interface that never went away.
@@ -5463,7 +5660,7 @@ mDNSlocal int SetupActiveInterfaces(mDNS *const m, mDNSs32 utc)
i->Occulting = !(i->ifa_flags & IFF_LOOPBACK) && (utc - i->LastSeen > 0 && utc - i->LastSeen < 60);
// Temporary fix to handle P2P flapping. P2P reuses the scope-id, mac address and the IP address
- // everytime it creates a new interface. We think it is a duplicate and hence consider it
+ // every time it creates a new interface. We think it is a duplicate and hence consider it
// as flashing and occulting, that is, flapping. If an interface is marked as flapping,
// mDNS_RegisterInterface() changes the probe delay from 1/2 second to 5 seconds and
// logs a warning message to system.log noting frequent interface transitions.
@@ -5488,7 +5685,42 @@ mDNSlocal int SetupActiveInterfaces(mDNS *const m, mDNSs32 utc)
n->InterfaceActive ? " (Primary)" : "");
if (!n->McastTxRx)
+ {
debugf("SetupActiveInterfaces: No Tx/Rx on %5s(%lu) %.6a InterfaceID %p %#a", i->ifinfo.ifname, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID, &n->ip);
+#if TARGET_OS_WATCH
+ // We join the Bonjour multicast group on the watch only when a client request is active,
+ // so we leave the multicast group here to clear any residual group membership.
+ if (i->sa_family == AF_INET)
+ {
+ struct ip_mreq imr;
+ primary->ifa_v4addr.s_addr = n->ip.ip.v4.NotAnInteger;
+ imr.imr_multiaddr.s_addr = AllDNSLinkGroup_v4.ip.v4.NotAnInteger;
+ imr.imr_interface = primary->ifa_v4addr;
+
+ if (SearchForInterfaceByName(m, i->ifinfo.ifname, AF_INET) == i)
+ {
+ LogInfo("SetupActiveInterfaces: %5s(%lu) Doing IP_DROP_MEMBERSHIP for %.4a on %.4a", i->ifinfo.ifname, i->scope_id, &imr.imr_multiaddr, &imr.imr_interface);
+ mStatus err = setsockopt(m->p->permanentsockets.sktv4, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr, sizeof(imr));
+ if (err < 0 && (errno != EADDRNOTAVAIL))
+ LogMsg("setsockopt - IP_DROP_MEMBERSHIP error %d errno %d (%s)", err, errno, strerror(errno));
+ }
+ }
+ if (i->sa_family == AF_INET6)
+ {
+ struct ipv6_mreq i6mr;
+ i6mr.ipv6mr_interface = primary->scope_id;
+ i6mr.ipv6mr_multiaddr = *(struct in6_addr*)&AllDNSLinkGroup_v6.ip.v6;
+
+ if (SearchForInterfaceByName(m, i->ifinfo.ifname, AF_INET6) == i)
+ {
+ LogInfo("SetupActiveInterfaces: %5s(%lu) Doing IPV6_LEAVE_GROUP for %.16a on %u", i->ifinfo.ifname, i->scope_id, &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);
+ mStatus err = setsockopt(m->p->permanentsockets.sktv6, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &i6mr, sizeof(i6mr));
+ if (err < 0 && (errno != EADDRNOTAVAIL))
+ LogMsg("setsockopt - IPV6_LEAVE_GROUP error %d errno %d (%s) group %.16a on %u", err, errno, strerror(errno), &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);
+ }
+ }
+#endif // TARGET_OS_WATCH
+ }
else
{
if (i->sa_family == AF_INET)
@@ -5559,7 +5791,7 @@ mDNSlocal void MarkAllInterfacesInactive(mDNS *const m, mDNSs32 utc)
}
}
-// returns count of non-link local V4 addresses deregistered
+// Returns count of non-link local V4 addresses deregistered (why? -- SC)
mDNSlocal int ClearInactiveInterfaces(mDNS *const m, mDNSs32 utc)
{
// First pass:
@@ -5585,7 +5817,7 @@ mDNSlocal int ClearInactiveInterfaces(mDNS *const m, mDNSs32 utc)
i->ifinfo.InterfaceActive ? " (Primary)" : "");
// Temporary fix to handle P2P flapping. P2P reuses the scope-id, mac address and the IP address
- // everytime it creates a new interface. We think it is a duplicate and hence consider it
+ // every time it creates a new interface. We think it is a duplicate and hence consider it
// as flashing and occulting. The "core" does not flush the cache for this case. This leads to
// stale data returned to the application even after the interface is removed. The application
// then starts to send data but the new interface is not yet created.
@@ -5801,7 +6033,6 @@ mDNSlocal void ConfigDNSServers(mDNS *const m, dns_resolver_t *r, mDNSInterfaceI
domainname d;
int serviceID = 0;
mDNSBool cellIntf = mDNSfalse;
- mDNSBool scopedDNS = mDNSfalse;
mDNSBool reqA, reqAAAA;
if (!r->domain || !*r->domain)
@@ -5814,11 +6045,7 @@ mDNSlocal void ConfigDNSServers(mDNS *const m, dns_resolver_t *r, mDNSInterfaceI
return;
}
// Parse the resolver specific attributes that affects all the DNS servers.
- if (scope == kScopeInterfaceID)
- {
- scopedDNS = mDNStrue;
- }
- else if (scope == kScopeServiceID)
+ if (scope == kScopeServiceID)
{
serviceID = r->service_identifier;
}
@@ -6107,124 +6334,114 @@ mDNSlocal void SetupActiveDirectoryDomain(dns_config_t *config)
mDNSlocal void SetupDDNSDomains(domainname *const fqdn, DNameListElem **RegDomains, DNameListElem **BrowseDomains)
{
int i;
- char buf[MAX_ESCAPED_DOMAIN_NAME]; // Max legal C-string name, including terminating NUL
+ char buf[MAX_ESCAPED_DOMAIN_NAME]; // Max legal C-string name, including terminating NULL
domainname d;
- SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:SetupDDNSDomains"), NULL, NULL);
- if (!store)
- {
- LogMsg("SetupDDNSDomains: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
- }
- else
+ CFDictionaryRef ddnsdict = SCDynamicStoreCopyValue(NULL, NetworkChangedKey_DynamicDNS);
+ if (ddnsdict)
{
- CFDictionaryRef ddnsdict = SCDynamicStoreCopyValue(store, NetworkChangedKey_DynamicDNS);
- if (ddnsdict)
+ if (fqdn)
{
- if (fqdn)
+ CFArrayRef fqdnArray = CFDictionaryGetValue(ddnsdict, CFSTR("HostNames"));
+ if (fqdnArray && CFArrayGetCount(fqdnArray) > 0)
{
- CFArrayRef fqdnArray = CFDictionaryGetValue(ddnsdict, CFSTR("HostNames"));
- if (fqdnArray && CFArrayGetCount(fqdnArray) > 0)
+ // for now, we only look at the first array element. if we ever support multiple configurations, we will walk the list
+ CFDictionaryRef fqdnDict = CFArrayGetValueAtIndex(fqdnArray, 0);
+ if (fqdnDict && DictionaryIsEnabled(fqdnDict))
{
- // for now, we only look at the first array element. if we ever support multiple configurations, we will walk the list
- CFDictionaryRef fqdnDict = CFArrayGetValueAtIndex(fqdnArray, 0);
- if (fqdnDict && DictionaryIsEnabled(fqdnDict))
+ CFStringRef name = CFDictionaryGetValue(fqdnDict, CFSTR("Domain"));
+ if (name)
{
- CFStringRef name = CFDictionaryGetValue(fqdnDict, CFSTR("Domain"));
- if (name)
- {
- if (!CFStringGetCString(name, buf, sizeof(buf), kCFStringEncodingUTF8) ||
- !MakeDomainNameFromDNSNameString(fqdn, buf) || !fqdn->c[0])
- LogMsg("GetUserSpecifiedDDNSConfig SCDynamicStore bad DDNS host name: %s", buf[0] ? buf : "(unknown)");
- else debugf("GetUserSpecifiedDDNSConfig SCDynamicStore DDNS host name: %s", buf);
- }
+ if (!CFStringGetCString(name, buf, sizeof(buf), kCFStringEncodingUTF8) ||
+ !MakeDomainNameFromDNSNameString(fqdn, buf) || !fqdn->c[0])
+ LogMsg("GetUserSpecifiedDDNSConfig SCDynamicStore bad DDNS host name: %s", buf[0] ? buf : "(unknown)");
+ else
+ debugf("GetUserSpecifiedDDNSConfig SCDynamicStore DDNS host name: %s", buf);
}
}
}
-
- if (RegDomains)
+ }
+ if (RegDomains)
+ {
+ CFArrayRef regArray = CFDictionaryGetValue(ddnsdict, CFSTR("RegistrationDomains"));
+ if (regArray && CFArrayGetCount(regArray) > 0)
{
- CFArrayRef regArray = CFDictionaryGetValue(ddnsdict, CFSTR("RegistrationDomains"));
- if (regArray && CFArrayGetCount(regArray) > 0)
+ CFDictionaryRef regDict = CFArrayGetValueAtIndex(regArray, 0);
+ if (regDict && DictionaryIsEnabled(regDict))
{
- CFDictionaryRef regDict = CFArrayGetValueAtIndex(regArray, 0);
- if (regDict && DictionaryIsEnabled(regDict))
+ CFStringRef name = CFDictionaryGetValue(regDict, CFSTR("Domain"));
+ if (name)
{
- CFStringRef name = CFDictionaryGetValue(regDict, CFSTR("Domain"));
- if (name)
+ if (!CFStringGetCString(name, buf, sizeof(buf), kCFStringEncodingUTF8) ||
+ !MakeDomainNameFromDNSNameString(&d, buf) || !d.c[0])
+ LogMsg("GetUserSpecifiedDDNSConfig SCDynamicStore bad DDNS registration domain: %s", buf[0] ? buf : "(unknown)");
+ else
{
- if (!CFStringGetCString(name, buf, sizeof(buf), kCFStringEncodingUTF8) ||
- !MakeDomainNameFromDNSNameString(&d, buf) || !d.c[0])
- LogMsg("GetUserSpecifiedDDNSConfig SCDynamicStore bad DDNS registration domain: %s", buf[0] ? buf : "(unknown)");
- else
- {
- debugf("GetUserSpecifiedDDNSConfig SCDynamicStore DDNS registration domain: %s", buf);
- AppendDNameListElem(&RegDomains, 0, &d);
- }
+ debugf("GetUserSpecifiedDDNSConfig SCDynamicStore DDNS registration domain: %s", buf);
+ AppendDNameListElem(&RegDomains, 0, &d);
}
}
}
}
-
- if (BrowseDomains)
+ }
+ if (BrowseDomains)
+ {
+ CFArrayRef browseArray = CFDictionaryGetValue(ddnsdict, CFSTR("BrowseDomains"));
+ if (browseArray)
{
- CFArrayRef browseArray = CFDictionaryGetValue(ddnsdict, CFSTR("BrowseDomains"));
- if (browseArray)
+ for (i = 0; i < CFArrayGetCount(browseArray); i++)
{
- for (i = 0; i < CFArrayGetCount(browseArray); i++)
+ CFDictionaryRef browseDict = CFArrayGetValueAtIndex(browseArray, i);
+ if (browseDict && DictionaryIsEnabled(browseDict))
{
- CFDictionaryRef browseDict = CFArrayGetValueAtIndex(browseArray, i);
- if (browseDict && DictionaryIsEnabled(browseDict))
+ CFStringRef name = CFDictionaryGetValue(browseDict, CFSTR("Domain"));
+ if (name)
{
- CFStringRef name = CFDictionaryGetValue(browseDict, CFSTR("Domain"));
- if (name)
+ if (!CFStringGetCString(name, buf, sizeof(buf), kCFStringEncodingUTF8) ||
+ !MakeDomainNameFromDNSNameString(&d, buf) || !d.c[0])
+ LogMsg("GetUserSpecifiedDDNSConfig SCDynamicStore bad DDNS browsing domain: %s", buf[0] ? buf : "(unknown)");
+ else
{
- if (!CFStringGetCString(name, buf, sizeof(buf), kCFStringEncodingUTF8) ||
- !MakeDomainNameFromDNSNameString(&d, buf) || !d.c[0])
- LogMsg("GetUserSpecifiedDDNSConfig SCDynamicStore bad DDNS browsing domain: %s", buf[0] ? buf : "(unknown)");
- else
- {
- debugf("GetUserSpecifiedDDNSConfig SCDynamicStore DDNS browsing domain: %s", buf);
- AppendDNameListElem(&BrowseDomains, 0, &d);
- }
+ debugf("GetUserSpecifiedDDNSConfig SCDynamicStore DDNS browsing domain: %s", buf);
+ AppendDNameListElem(&BrowseDomains, 0, &d);
}
}
}
}
}
- CFRelease(ddnsdict);
}
-
- if (RegDomains)
+ CFRelease(ddnsdict);
+ }
+ if (RegDomains)
+ {
+ CFDictionaryRef btmm = SCDynamicStoreCopyValue(NULL, NetworkChangedKey_BackToMyMac);
+ if (btmm)
{
- CFDictionaryRef btmm = SCDynamicStoreCopyValue(store, NetworkChangedKey_BackToMyMac);
- if (btmm)
+ CFIndex size = CFDictionaryGetCount(btmm);
+ const void *key[size];
+ const void *val[size];
+ CFDictionaryGetKeysAndValues(btmm, key, val);
+ for (i = 0; i < size; i++)
{
- CFIndex size = CFDictionaryGetCount(btmm);
- const void *key[size];
- const void *val[size];
- CFDictionaryGetKeysAndValues(btmm, key, val);
- for (i = 0; i < size; i++)
+ LogInfo("BackToMyMac %d", i);
+ if (!CFStringGetCString(key[i], buf, sizeof(buf), kCFStringEncodingUTF8))
+ LogMsg("Can't read BackToMyMac %d key %s", i, buf);
+ else
{
- LogInfo("BackToMyMac %d", i);
- if (!CFStringGetCString(key[i], buf, sizeof(buf), kCFStringEncodingUTF8))
- LogMsg("Can't read BackToMyMac %d key %s", i, buf);
- else
+ mDNSu32 uid = atoi(buf);
+ if (!CFStringGetCString(val[i], buf, sizeof(buf), kCFStringEncodingUTF8))
+ LogMsg("Can't read BackToMyMac %d val %s", i, buf);
+ else if (MakeDomainNameFromDNSNameString(&d, buf) && d.c[0])
{
- mDNSu32 uid = atoi(buf);
- if (!CFStringGetCString(val[i], buf, sizeof(buf), kCFStringEncodingUTF8))
- LogMsg("Can't read BackToMyMac %d val %s", i, buf);
- else if (MakeDomainNameFromDNSNameString(&d, buf) && d.c[0])
- {
- LogInfo("BackToMyMac %d %d %##s", i, uid, d.c);
- AppendDNameListElem(&RegDomains, uid, &d);
- }
+ LogInfo("BackToMyMac %d %d %##s", i, uid, d.c);
+ AppendDNameListElem(&RegDomains, uid, &d);
}
}
- CFRelease(btmm);
}
+ CFRelease(btmm);
}
- CFRelease(store);
}
+
}
// Returns mDNSfalse, if it does not set the configuration i.e., if the DNS configuration did not change
@@ -6296,7 +6513,6 @@ mDNSexport mDNSBool mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers,
dns_config_t *config = dns_configuration_copy();
if (!config)
{
- // When running on 10.3 (build 7xxx) and earlier, we don't expect dns_configuration_copy() to succeed
// On 10.4, calls to dns_configuration_copy() early in the boot process often fail.
// Apparently this is expected behaviour -- "not a bug".
// Accordingly, we suppress syslog messages for the first three minutes after boot.
@@ -6355,8 +6571,6 @@ mDNSexport mDNSBool mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers,
}
dns_configuration_free(config);
if (setsearch) FinalizeSearchDomainHash(m, &sdc);
- setservers = mDNSfalse; // Done these now -- no need to fetch the same data from SCDynamicStore
- setsearch = mDNSfalse;
}
}
#endif // MDNS_NO_DNSINFO
@@ -6369,81 +6583,78 @@ mDNSexport mStatus mDNSPlatformGetPrimaryInterface(mDNS *const m, mDNSAddr *v4,
{
char buf[256];
(void)m; // Unused
-
- SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:mDNSPlatformGetPrimaryInterface"), NULL, NULL);
- if (!store)
- LogMsg("mDNSPlatformGetPrimaryInterface: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
- else
+
+ CFDictionaryRef dict = SCDynamicStoreCopyValue(NULL, NetworkChangedKey_IPv4);
+ if (dict)
{
- CFDictionaryRef dict = SCDynamicStoreCopyValue(store, NetworkChangedKey_IPv4);
- if (dict)
+ r->type = mDNSAddrType_IPv4;
+ r->ip.v4 = zerov4Addr;
+ CFStringRef string = CFDictionaryGetValue(dict, kSCPropNetIPv4Router);
+ if (string)
{
- r->type = mDNSAddrType_IPv4;
- r->ip.v4 = zerov4Addr;
- CFStringRef string = CFDictionaryGetValue(dict, kSCPropNetIPv4Router);
- if (string)
+ if (!CFStringGetCString(string, buf, 256, kCFStringEncodingUTF8))
+ LogMsg("Could not convert router to CString");
+ else
{
- if (!CFStringGetCString(string, buf, 256, kCFStringEncodingUTF8))
- LogMsg("Could not convert router to CString");
- else
- {
- struct sockaddr_in saddr;
- saddr.sin_len = sizeof(saddr);
- saddr.sin_family = AF_INET;
- saddr.sin_port = 0;
- inet_aton(buf, &saddr.sin_addr);
-
- *(in_addr_t *)&r->ip.v4 = saddr.sin_addr.s_addr;
- }
+ struct sockaddr_in saddr;
+ saddr.sin_len = sizeof(saddr);
+ saddr.sin_family = AF_INET;
+ saddr.sin_port = 0;
+ inet_aton(buf, &saddr.sin_addr);
+ *(in_addr_t *)&r->ip.v4 = saddr.sin_addr.s_addr;
}
+ }
+ string = CFDictionaryGetValue(dict, kSCDynamicStorePropNetPrimaryInterface);
+ if (string)
+ {
+ mDNSBool HavePrimaryGlobalv6 = mDNSfalse; // does the primary interface have a global v6 address?
+ struct ifaddrs *ifa = myGetIfAddrs(1);
+ *v4 = *v6 = zeroAddr;
- string = CFDictionaryGetValue(dict, kSCDynamicStorePropNetPrimaryInterface);
- if (string)
+ if (!CFStringGetCString(string, buf, 256, kCFStringEncodingUTF8))
+ {
+ LogMsg("Could not convert router to CString");
+ goto exit;
+ }
+ // find primary interface in list
+ while (ifa && (mDNSIPv4AddressIsZero(v4->ip.v4) || mDNSv4AddressIsLinkLocal(&v4->ip.v4) || !HavePrimaryGlobalv6))
{
- mDNSBool HavePrimaryGlobalv6 = mDNSfalse; // does the primary interface have a global v6 address?
- struct ifaddrs *ifa = myGetIfAddrs(1);
-
- *v4 = *v6 = zeroAddr;
-
- if (!CFStringGetCString(string, buf, 256, kCFStringEncodingUTF8)) { LogMsg("Could not convert router to CString"); goto exit; }
-
- // find primary interface in list
- while (ifa && (mDNSIPv4AddressIsZero(v4->ip.v4) || mDNSv4AddressIsLinkLocal(&v4->ip.v4) || !HavePrimaryGlobalv6))
+ mDNSAddr tmp6 = zeroAddr;
+ if (!strcmp(buf, ifa->ifa_name))
{
- mDNSAddr tmp6 = zeroAddr;
- if (!strcmp(buf, ifa->ifa_name))
+ if (ifa->ifa_addr->sa_family == AF_INET)
{
- if (ifa->ifa_addr->sa_family == AF_INET)
- {
- if (mDNSIPv4AddressIsZero(v4->ip.v4) || mDNSv4AddressIsLinkLocal(&v4->ip.v4)) SetupAddr(v4, ifa->ifa_addr);
- }
- else if (ifa->ifa_addr->sa_family == AF_INET6)
- {
- SetupAddr(&tmp6, ifa->ifa_addr);
- if (tmp6.ip.v6.b[0] >> 5 == 1) // global prefix: 001
- { HavePrimaryGlobalv6 = mDNStrue; *v6 = tmp6; }
- }
+ if (mDNSIPv4AddressIsZero(v4->ip.v4) || mDNSv4AddressIsLinkLocal(&v4->ip.v4))
+ SetupAddr(v4, ifa->ifa_addr);
}
- else
+ else if (ifa->ifa_addr->sa_family == AF_INET6)
{
- // We'll take a V6 address from the non-primary interface if the primary interface doesn't have a global V6 address
- if (!HavePrimaryGlobalv6 && ifa->ifa_addr->sa_family == AF_INET6 && !v6->ip.v6.b[0])
- {
- SetupAddr(&tmp6, ifa->ifa_addr);
- if (tmp6.ip.v6.b[0] >> 5 == 1) *v6 = tmp6;
+ SetupAddr(&tmp6, ifa->ifa_addr);
+ if (tmp6.ip.v6.b[0] >> 5 == 1) // global prefix: 001
+ {
+ HavePrimaryGlobalv6 = mDNStrue;
+ *v6 = tmp6;
}
}
- ifa = ifa->ifa_next;
}
-
- // Note that while we advertise v6, we still require v4 (possibly NAT'd, but not link-local) because we must use
- // V4 to communicate w/ our DNS server
+ else
+ {
+ // We'll take a V6 address from the non-primary interface if the primary interface doesn't have a global V6 address
+ if (!HavePrimaryGlobalv6 && ifa->ifa_addr->sa_family == AF_INET6 && !v6->ip.v6.b[0])
+ {
+ SetupAddr(&tmp6, ifa->ifa_addr);
+ if (tmp6.ip.v6.b[0] >> 5 == 1)
+ *v6 = tmp6;
+ }
+ }
+ ifa = ifa->ifa_next;
}
+ // Note that while we advertise v6, we still require v4 (possibly NAT'd, but not link-local) because we must use
+ // V4 to communicate w/ our DNS server
+ }
exit:
- CFRelease(dict);
- }
- CFRelease(store);
+ CFRelease(dict);
}
return mStatus_NoError;
}
@@ -6941,57 +7152,20 @@ mDNSlocal void SetLocalDomains(void)
mDNSlocal void GetCurrentPMSetting(const CFStringRef name, mDNSs32 *val)
{
-#if USE_IOPMCOPYACTIVEPMPREFERENCES
- CFTypeRef blob = NULL;
- CFStringRef str = NULL;
- CFDictionaryRef odict = NULL;
- CFDictionaryRef idict = NULL;
- CFNumberRef number = NULL;
-
- blob = IOPSCopyPowerSourcesInfo();
- if (!blob) { LogMsg("GetCurrentPMSetting: IOPSCopyPowerSourcesInfo failed!"); goto end; }
-
- odict = IOPMCopyActivePMPreferences();
- if (!odict) { LogMsg("GetCurrentPMSetting: IOPMCopyActivePMPreferences failed!"); goto end; }
-
- str = IOPSGetProvidingPowerSourceType(blob);
- if (!str) { LogMsg("GetCurrentPMSetting: IOPSGetProvidingPowerSourceType failed!"); goto end; }
-
- idict = CFDictionaryGetValue(odict, str);
- if (!idict)
+
+ CFDictionaryRef dict = SCDynamicStoreCopyValue(NULL, NetworkChangedKey_PowerSettings);
+ if (!dict)
{
- char buf[256];
- if (!CFStringGetCString(str, buf, sizeof(buf), kCFStringEncodingUTF8)) buf[0] = 0;
- LogMsg("GetCurrentPMSetting: CFDictionaryGetValue (%s) failed!", buf);
- goto end;
+ LogSPS("GetCurrentPMSetting: Could not get IOPM CurrentSettings dict");
}
-
- number = CFDictionaryGetValue(idict, name);
- if (!number || CFGetTypeID(number) != CFNumberGetTypeID() || !CFNumberGetValue(number, kCFNumberSInt32Type, val))
- *val = 0;
-end:
- if (blob) CFRelease(blob);
- if (odict) CFRelease(odict);
-
-#else
-
- SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:GetCurrentPMSetting"), NULL, NULL);
- if (!store) LogMsg("GetCurrentPMSetting: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
else
{
- CFDictionaryRef dict = SCDynamicStoreCopyValue(store, NetworkChangedKey_PowerSettings);
- if (!dict) LogSPS("GetCurrentPMSetting: Could not get IOPM CurrentSettings dict");
- else
- {
- CFNumberRef number = CFDictionaryGetValue(dict, name);
- if (!number || CFGetTypeID(number) != CFNumberGetTypeID() || !CFNumberGetValue(number, kCFNumberSInt32Type, val))
- *val = 0;
- CFRelease(dict);
- }
- CFRelease(store);
+ CFNumberRef number = CFDictionaryGetValue(dict, name);
+ if (!number || CFGetTypeID(number) != CFNumberGetTypeID() || !CFNumberGetValue(number, kCFNumberSInt32Type, val))
+ *val = 0;
+ CFRelease(dict);
}
-
-#endif
+
}
#if APPLE_OSX_mDNSResponder
@@ -7301,6 +7475,10 @@ mDNSlocal mDNSu32 CountProxyRecords(mDNS *const m, uint32_t *const numbytes, Net
// attempt to update the record again.
if (isKeepAliveRecord && (UpdateKeepaliveRData(m, rr, intf, mDNSfalse, mDNSNULL) != mStatus_NoError))
LogSPS("CountProxyRecords: Failed to update keepalive record - %s", ARDisplayString(m, rr));
+
+ // Offload only Valid Keepalive records
+ if (isKeepAliveRecord && !mDNSValidKeepAliveRecord(rr))
+ continue;
#else
(void) TCPKAOnly; // unused
(void) supportsTCPKA; // unused
@@ -7338,6 +7516,10 @@ mDNSlocal void GetProxyRecords(mDNS *const m, DNSMessage *const msg, uint32_t *c
// Skip over TCP KeepAlive records if the policy prohibits it or if the interface does not support TCP Keepalive
if ((TCPKAOnly && !isKeepAliveRecord) || (isKeepAliveRecord && !supportsTCPKA))
continue;
+
+ // Offload only Valid Keepalive records
+ if (isKeepAliveRecord && !mDNSValidKeepAliveRecord(rr))
+ continue;
#else
(void) TCPKAOnly; // unused
(void) supportsTCPKA; // unused
@@ -7360,29 +7542,6 @@ mDNSlocal void GetProxyRecords(mDNS *const m, DNSMessage *const msg, uint32_t *c
*numbytes = p - msg->data;
}
-// If compiling with old headers and libraries (pre 10.5) that don't include IOConnectCallStructMethod
-// then we declare a dummy version here so that the code at least compiles
-#ifndef AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER
-static kern_return_t
-IOConnectCallStructMethod(
- mach_port_t connection, // In
- uint32_t selector, // In
- const void *inputStruct, // In
- size_t inputStructCnt, // In
- void *outputStruct, // Out
- size_t *outputStructCnt) // In/Out
-{
- (void)connection;
- (void)selector;
- (void)inputStruct;
- (void)inputStructCnt;
- (void)outputStruct;
- (void)outputStructCnt;
- LogMsg("Compiled without IOConnectCallStructMethod");
- return(KERN_FAILURE);
-}
-#endif
-
mDNSexport mDNSBool SupportsInNICProxy(NetworkInterfaceInfo *const intf)
{
if(!UseInternalSleepProxy)
@@ -7393,12 +7552,12 @@ mDNSexport mDNSBool SupportsInNICProxy(NetworkInterfaceInfo *const intf)
return CheckInterfaceSupport(intf, mDNS_IOREG_KEY);
}
-mDNSexport mStatus ActivateLocalProxy(mDNS *const m, NetworkInterfaceInfo *const intf) // Called with the lock held
+mDNSexport mStatus ActivateLocalProxy(mDNS *const m, NetworkInterfaceInfo *const intf, mDNSBool *keepaliveOnly) // Called with the lock held
{
mStatus result = mStatus_UnknownErr;
mDNSBool TCPKAOnly = mDNSfalse;
mDNSBool supportsTCPKA = mDNSfalse;
- mDNSBool onbattery = mDNSfalse;
+ mDNSBool onbattery = mDNSfalse;
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOBSDNameMatching(kIOMasterPortDefault, 0, intf->ifname));
#if APPLE_OSX_mDNSResponder && !TARGET_OS_EMBEDDED
@@ -7489,6 +7648,7 @@ mDNSexport mStatus ActivateLocalProxy(mDNS *const m, NetworkInterfaceInfo *const
IOObjectRelease(parent);
}
IOObjectRelease(service);
+ *keepaliveOnly = TCPKAOnly;
return result;
}
@@ -7638,18 +7798,10 @@ mDNSlocal mDNSv6Addr IPv6AddressFromString(char* buf)
mDNSlocal CFDictionaryRef CopyConnectivityBackToMyMacDict()
{
- SCDynamicStoreRef store = NULL;
CFDictionaryRef connd = NULL;
CFDictionaryRef BTMMDict = NULL;
- store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:CopyConnectivityBackToMyMacDict"), NULL, NULL);
- if (!store)
- {
- LogMsg("CopyConnectivityBackToMyMacDict: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
- goto end;
- }
-
- connd = SCDynamicStoreCopyValue(store, NetworkChangedKey_BTMMConnectivity);
+ connd = SCDynamicStoreCopyValue(NULL, NetworkChangedKey_BTMMConnectivity);
if (!connd)
{
LogInfo("CopyConnectivityBackToMyMacDict: SCDynamicStoreCopyValue failed: %s", SCErrorString(SCError()));
@@ -7675,7 +7827,6 @@ mDNSlocal CFDictionaryRef CopyConnectivityBackToMyMacDict()
end:
if (connd) CFRelease(connd);
- if (store) CFRelease(store);
return BTMMDict;
}
@@ -7844,12 +7995,76 @@ mDNSlocal mDNSBool IsAppleNetwork(mDNS *const m)
return mDNSfalse;
}
+// Called with KQueueLock & mDNS lock
+// SetNetworkChanged is allowed to shorten (but not extend) the pause while we wait for configuration changes to settle
+mDNSlocal void SetNetworkChanged(mDNS *const m, mDNSs32 delay)
+{
+ mDNS_CheckLock(m);
+ if (!m->NetworkChanged || m->NetworkChanged - NonZeroTime(m->timenow + delay) > 0)
+ {
+ m->NetworkChanged = NonZeroTime(m->timenow + delay);
+ LogInfo("SetNetworkChanged: Scheduling in %d ticks", delay);
+ }
+ else
+ LogInfo("SetNetworkChanged: *NOT* increasing delay from %d to %d", m->NetworkChanged - m->timenow, delay);
+}
+
+// Called with KQueueLock & mDNS lock
+mDNSlocal void SetKeyChainTimer(mDNS *const m, mDNSs32 delay)
+{
+ // If it's not set or it needs to happen sooner than when it's currently set
+ if (!m->p->KeyChainTimer || m->p->KeyChainTimer - NonZeroTime(m->timenow + delay) > 0)
+ {
+ m->p->KeyChainTimer = NonZeroTime(m->timenow + delay);
+ LogInfo("SetKeyChainTimer: %d", delay);
+ }
+}
+
mDNSexport void mDNSMacOSXNetworkChanged(mDNS *const m)
{
- LogInfo("*** Network Configuration Change *** (%d)%s",
- m->p->NetworkChanged ? mDNS_TimeNow(m) - m->p->NetworkChanged : 0,
- m->p->NetworkChanged ? "" : " (no scheduled configuration change)");
- m->p->NetworkChanged = 0; // If we received a network change event and deferred processing, we're now dealing with it
+ LogInfo("*** Network Configuration Change *** %d ticks late%s",
+ m->NetworkChanged ? mDNS_TimeNow(m) - m->NetworkChanged : 0,
+ m->NetworkChanged ? "" : " (no scheduled configuration change)");
+ m->NetworkChanged = 0; // If we received a network change event and deferred processing, we're now dealing with it
+
+ // If we have any NOTREADY IPv6 addresses, wait until they've finished configuring
+ int InfoSocket = socket(AF_INET6, SOCK_DGRAM, 0);
+ if (InfoSocket > 0)
+ {
+ mDNSBool notready = mDNSfalse;
+ struct ifaddrs *ifa = myGetIfAddrs(1);
+ while (ifa)
+ {
+ if (ifa->ifa_addr->sa_family == AF_INET6)
+ {
+ struct in6_ifreq ifr6;
+ mDNSPlatformMemZero((char *)&ifr6, sizeof(ifr6));
+ strlcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name));
+ ifr6.ifr_addr = *(struct sockaddr_in6 *)ifa->ifa_addr;
+ // We need to check for IN6_IFF_TENTATIVE here, not IN6_IFF_NOTREADY, because
+ // IN6_IFF_NOTREADY includes both IN6_IFF_TENTATIVE and IN6_IFF_DUPLICATED addresses.
+ // We can expect that an IN6_IFF_TENTATIVE address will shortly become ready,
+ // but an IN6_IFF_DUPLICATED address may not.
+ if (ioctl(InfoSocket, SIOCGIFAFLAG_IN6, &ifr6) != -1)
+ if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_TENTATIVE)
+ {
+ LogInfo("*** Network Configuration Change *** IPv6 address %.16a TENTATIVE, will retry", &ifr6.ifr_addr.sin6_addr);
+ notready = mDNStrue;
+ }
+ }
+ ifa = ifa->ifa_next;
+ }
+ close(InfoSocket);
+ if (notready)
+ {
+ mDNS_Lock(m);
+ SetNetworkChanged(m, mDNSPlatformOneSecond / 2);
+ mDNS_Unlock(m);
+ return;
+ }
+ LogInfo("*** Network Configuration Change *** No IPv6 address NOTREADY, will continue");
+ }
+
mDNSs32 utc = mDNSPlatformUTC();
m->SystemWakeOnLANEnabled = SystemWakeForNetworkAccess();
m->SystemSleepOnlyIfWakeOnLAN = SystemSleepOnlyIfWakeOnLAN();
@@ -7933,36 +8148,12 @@ mDNSexport void mDNSMacOSXNetworkChanged(mDNS *const m)
if (IsAppleNetwork(m) != mDNS_McastTracingEnabled)
{
mDNS_McastTracingEnabled = mDNS_McastTracingEnabled ? mDNSfalse : mDNStrue;
- LogMsg("mDNSMacOSXNetworkChanged: Multicast Tracing %s", mDNS_McastTracingEnabled ? "Enabled" : "Disabled");
+ LogInfo("mDNSMacOSXNetworkChanged: Multicast Tracing %s", mDNS_McastTracingEnabled ? "Enabled" : "Disabled");
UpdateDebugState();
}
}
-// Called with KQueueLock & mDNS lock
-// SetNetworkChanged is allowed to extend (but not reduce) the pause while we wait for configuration changes to settle
-mDNSlocal void SetNetworkChanged(mDNS *const m, mDNSs32 delay)
-{
- if (!m->p->NetworkChanged || m->p->NetworkChanged - NonZeroTime(m->timenow + delay) < 0)
- {
- m->p->NetworkChanged = NonZeroTime(m->timenow + delay);
- LogInfo("SetNetworkChanged: Scheduling in %d msec", delay);
- }
- else
- LogInfo("SetNetworkChanged: *NOT* reducing delay from %d to %d", m->p->NetworkChanged - m->timenow, delay);
-}
-
-// Called with KQueueLock & mDNS lock
-mDNSlocal void SetKeyChainTimer(mDNS *const m, mDNSs32 delay)
-{
- // If it's not set or it needs to happen sooner than when it's currently set
- if (!m->p->KeyChainTimer || m->p->KeyChainTimer - NonZeroTime(m->timenow + delay) > 0)
- {
- m->p->KeyChainTimer = NonZeroTime(m->timenow + delay);
- LogInfo("SetKeyChainTimer: %d", delay);
- }
-}
-
// Copy the fourth slash-delimited element from either:
// State:/Network/Interface/<bsdname>/IPv4
// or
@@ -7983,7 +8174,6 @@ mDNSlocal CFStringRef CopyNameFromKey(CFStringRef key)
// an IP service that is explicitly configured for IPv4 Link Local
mDNSlocal int ChangedKeysHaveIPv4LL(CFArrayRef inkeys)
{
- SCDynamicStoreRef store = NULL;
CFDictionaryRef dict = NULL;
CFMutableArrayRef a;
const void **keys = NULL, **vals = NULL;
@@ -7994,9 +8184,6 @@ mDNSlocal int ChangedKeysHaveIPv4LL(CFArrayRef inkeys)
jc = CFArrayGetCount(inkeys);
if (!jc) goto done;
- store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:ChangedKeysHaveIPv4LL"), NULL, NULL);
- if (store == NULL) goto done;
-
a = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
if (a == NULL) goto done;
@@ -8012,7 +8199,7 @@ mDNSlocal int ChangedKeysHaveIPv4LL(CFArrayRef inkeys)
CFArrayAppendValue(a, pattern);
CFRelease(pattern);
- dict = SCDynamicStoreCopyMultiple(store, NULL, a);
+ dict = SCDynamicStoreCopyMultiple(NULL, NULL, a);
CFRelease(a);
if (!dict)
@@ -8094,7 +8281,6 @@ done:
if (vals != NULL) mDNSPlatformMemFree(vals);
if (keys != NULL) mDNSPlatformMemFree(keys);
if (dict != NULL) CFRelease(dict);
- if (store != NULL) CFRelease(store);
return found;
}
@@ -8106,20 +8292,22 @@ mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, v
KQueueLock(m);
mDNS_Lock(m);
- mDNSs32 delay = mDNSPlatformOneSecond * 2; // Start off assuming a two-second delay
+ //mDNSs32 delay = mDNSPlatformOneSecond * 2; // Start off assuming a two-second delay
+ const mDNSs32 delay = (mDNSPlatformOneSecond + 39) / 40; // 25 ms delay
int c = CFArrayGetCount(changedKeys); // Count changes
CFRange range = { 0, c };
- int c1 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_Hostnames ) != 0);
- int c2 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_Computername) != 0);
- int c3 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_DNS ) != 0);
- int c4 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_DynamicDNS ) != 0);
- int c5 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_BackToMyMac ) != 0);
- int c6 = ChangedKeysHaveIPv4LL(changedKeys);
- int c7 = 0;
-
+ int c_host = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_Hostnames ) != 0);
+ int c_comp = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_Computername) != 0);
+ int c_udns = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_DNS ) != 0);
+ int c_ddns = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_DynamicDNS ) != 0);
+ int c_btmm = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_BackToMyMac ) != 0);
+ int c_v4ll = ChangedKeysHaveIPv4LL(changedKeys);
+ int c_fast = 0;
+
// Do immediate network changed processing for "p2p*" interfaces and
- // for interfaces with the IFEF_DIRECTLINK flag set.
+ // for interfaces with the IFEF_DIRECTLINK flag set or association with a CarPlay
+ // hosted SSID.
{
CFArrayRef labels;
CFIndex n;
@@ -8149,10 +8337,10 @@ mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, v
// The 4th label (index = 3) should be the interface name.
if (CFStringGetCString(CFArrayGetValueAtIndex(labels, 3), buf, sizeof(buf), kCFStringEncodingUTF8)
- && (strstr(buf, "p2p") || (getExtendedFlags(buf) & IFEF_DIRECTLINK)))
+ && (strstr(buf, "p2p") || (getExtendedFlags(buf) & IFEF_DIRECTLINK) || IsCarPlaySSID(buf)))
{
LogInfo("NetworkChanged: interface %s qualifies for reduced change handling delay", buf);
- c7++;
+ c_fast++;
CFRelease(labels);
break;
}
@@ -8161,22 +8349,8 @@ mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, v
}
}
- if (c && c - c1 - c2 - c3 - c4 - c5 - c6 - c7 == 0)
- delay = mDNSPlatformOneSecond/10; // If these were the only changes, shorten delay
-
- // Immediately force a reconfig (esp. cache flush) if any of the following is true:
- // 1. DNS Settings changed.
- // 2 An interface changed that is explicitly IPv4 link local
- // 3. There are P2P/IFEF_DIRECTLINK/IsCarPlaySSID changes
- if (c3 || ChangedKeysHaveIPv4LL(changedKeys) || c7)
- {
- LogInfo("NetworkChanged: %s : Handling this change immediately",
- c3 ? "DNS Settings Changed" :
- c7 ? "P2P/IFEF_DIRECTLINK/IsCarPlaySSID Changed" :
- "An interface changed that is explicitly IPv4 link local");
- m->p->NetworkChanged = NonZeroTime(m->timenow);
- delay = 0; // for the logs below.
- }
+ //if (c && c - c_host - c_comp - c_udns - c_ddns - c_btmm - c_v4ll - c_fast == 0)
+ // delay = mDNSPlatformOneSecond/10; // If these were the only changes, shorten delay
if (mDNS_LoggingEnabled)
{
@@ -8185,19 +8359,19 @@ mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, v
{
char buf[256];
if (!CFStringGetCString(CFArrayGetValueAtIndex(changedKeys, i), buf, sizeof(buf), kCFStringEncodingUTF8)) buf[0] = 0;
- LogInfo("*** NetworkChanged SC key: %s", buf);
+ LogInfo("*** Network Configuration Change *** SC key: %s", buf);
}
- LogInfo("*** NetworkChanged *** %d change%s %s%s%s%s%s%s%sdelay %d%s",
+ LogInfo("*** Network Configuration Change *** %d change%s %s%s%s%s%s%s%sdelay %d%s",
c, c>1 ? "s" : "",
- c1 ? "(Local Hostname) " : "",
- c2 ? "(Computer Name) " : "",
- c3 ? "(DNS) " : "",
- c4 ? "(DynamicDNS) " : "",
- c5 ? "(BTMM) " : "",
- c6 ? "(kSCValNetIPv4ConfigMethodLinkLocal) " : "",
- c7 ? "(P2P/IFEF_DIRECTLINK/IsCarPlaySSID) " : "",
+ c_host ? "(Local Hostname) " : "",
+ c_comp ? "(Computer Name) " : "",
+ c_udns ? "(DNS) " : "",
+ c_ddns ? "(DynamicDNS) " : "",
+ c_btmm ? "(BTMM) " : "",
+ c_v4ll ? "(kSCValNetIPv4ConfigMethodLinkLocal) " : "",
+ c_fast ? "(P2P/IFEF_DIRECTLINK/IsCarPlaySSID) " : "",
delay,
- (c4 || c5) ? " + SetKeyChainTimer" : "");
+ (c_ddns || c_btmm) ? " + SetKeyChainTimer" : "");
}
SetNetworkChanged(m, delay);
@@ -8207,11 +8381,12 @@ mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, v
// setup the DomainAuthInfo before handing the network change.
// If we don't, then we will first try to register services in the clear, then later setup the
// DomainAuthInfo, which is incorrect.
- if (c4 || c5)
+ if (c_ddns || c_btmm)
SetKeyChainTimer(m, delay);
- mDNS_Unlock(m);
+ // Don't try to call mDNSMacOSXNetworkChanged() here -- we're running on the wrong thread
+ mDNS_Unlock(m);
KQueueUnlock(m, "NetworkChanged");
}
@@ -8285,7 +8460,7 @@ mDNSlocal mStatus WatchForNetworkChanges(mDNS *const m)
CFArrayAppendValue(keys, NetworkChangedKey_DNS);
CFArrayAppendValue(keys, NetworkChangedKey_DynamicDNS);
CFArrayAppendValue(keys, NetworkChangedKey_BackToMyMac);
- CFArrayAppendValue(keys, NetworkChangedKey_PowerSettings); // should remove as part of <rdar://problem/6751656>
+ CFArrayAppendValue(keys, NetworkChangedKey_PowerSettings);
CFArrayAppendValue(keys, NetworkChangedKey_BTMMConnectivity);
CFArrayAppendValue(patterns, pattern1);
CFArrayAppendValue(patterns, pattern2);
@@ -8318,33 +8493,6 @@ exit:
return(err);
}
-#if 0 // <rdar://problem/6751656>
-mDNSlocal void PMChanged(void *context)
-{
- mDNS *const m = (mDNS *const)context;
-
- KQueueLock(m);
- mDNS_Lock(m);
-
- LogSPS("PMChanged");
-
- SetNetworkChanged(m, mDNSPlatformOneSecond * 2);
-
- mDNS_Unlock(m);
- KQueueUnlock(m, "PMChanged");
-}
-
-mDNSlocal mStatus WatchForPMChanges(mDNS *const m)
-{
- m->p->PMRLS = IOPMPrefsNotificationCreateRunLoopSource(PMChanged, m);
- if (!m->p->PMRLS) { LogMsg("IOPMPrefsNotificationCreateRunLoopSource failed!"); return mStatus_UnknownErr; }
-
- CFRunLoopAddSource(CFRunLoopGetCurrent(), m->p->PMRLS, kCFRunLoopDefaultMode);
-
- return mStatus_NoError;
-}
-#endif
-
#if !TARGET_OS_EMBEDDED // don't setup packet filter rules on embedded
mDNSlocal void mDNSSetPacketFilterRules(mDNS *const m, char * ifname, const ResourceRecord *const excludeRecord)
@@ -8450,12 +8598,9 @@ mDNSlocal void newMasterElected(mDNS *const m, struct net_event_data * ptr)
LogInfo("newMasterElected: ifname = %s, interfaceIndex = %d", ifname, interfaceIndex);
infoOSX = IfindexToInterfaceInfoOSX(m, (mDNSInterfaceID)(uintptr_t)interfaceIndex);
-
- // Can get an KEV_DL_MASTER_ELECTED event prior to the interface existing
- // when it is first brought up.
if (!infoOSX)
{
- LogInfo("newMasterElected: interface not yet active");
+ LogInfo("newMasterElected: interface %s not yet active", ifname);
return;
}
InterfaceID = infoOSX->ifinfo.InterfaceID;
@@ -8516,13 +8661,18 @@ mDNSlocal void removeCachedPeerRecords(mDNS *const m, mDNSu32 ifindex, mDNSAddr
mDNSu32 slot;
CacheGroup *cg;
CacheRecord *cr;
- mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(m, ifindex);
+ NetworkInterfaceInfoOSX *infoOSX;
+ mDNSInterfaceID InterfaceID;
- if (!InterfaceID)
+ // Using mDNSPlatformInterfaceIDfromInterfaceIndex() would lead to recursive
+ // locking issues, see: <rdar://problem/21332983>
+ infoOSX = IfindexToInterfaceInfoOSX(m, (mDNSInterfaceID)(uintptr_t)ifindex);
+ if (!infoOSX)
{
- LogInfo("removeCachedPeerRecords: Invalid ifindex: %d", ifindex);
+ LogInfo("removeCachedPeerRecords: interface %d not yet active", ifindex);
return;
}
+ InterfaceID = infoOSX->ifinfo.InterfaceID;
FORALL_CACHERECORDS(slot, cg, cr)
{
@@ -8771,6 +8921,12 @@ mDNSlocal OSStatus KeychainChanged(SecKeychainEvent keychainEvent, SecKeychainCa
mDNSlocal void PowerOn(mDNS *const m)
{
mDNSCoreMachineSleep(m, false); // Will set m->SleepState = SleepState_Awake;
+
+ // Hold on to a sleep assertion to allow mDNSResponder to perform its maintenance activities.
+ // This allows for the network link to come up, DHCP to get an address, mDNS to issue queries etc.
+ // We will clear this assertion as soon as we think the mainenance activities are done.
+ mDNSPlatformPreventSleep(m, DARK_WAKE_TIME, "mDNSResponder:maintenance");
+
if (m->p->WakeAtUTC)
{
long utc = mDNSPlatformUTC();
@@ -9526,7 +9682,7 @@ mDNSlocal mDNSBool EtcHostsDeleteOldEntries(mDNS *const m, AuthHash *newhosts, m
{
AuthGroup *ag;
mDNSu32 slot;
- AuthRecord *rr, *primary, *rrnext;
+ AuthRecord *rr, *rrnext;
for (slot = 0; slot < AUTH_HASH_SLOTS; slot++)
for (ag = m->rrauth.rrauth_hash[slot]; ag; ag = ag->next)
for (rr = ag->members; rr; rr = rrnext)
@@ -9539,7 +9695,7 @@ mDNSlocal mDNSBool EtcHostsDeleteOldEntries(mDNS *const m, AuthHash *newhosts, m
ag1 = AuthGroupForRecord(newhosts, slot, &rr->resrec);
if (ag1)
{
- primary = rr1 = ag1->members;
+ rr1 = ag1->members;
while (rr1)
{
if (IdenticalResourceRecord(&rr1->resrec, &rr->resrec))
@@ -9912,14 +10068,16 @@ mDNSlocal mStatus mDNSPlatformInit_setup(mDNS *const m)
m->p->permanentsockets.sktv4 = -1;
m->p->permanentsockets.kqsv4.KQcallback = myKQSocketCallBack;
m->p->permanentsockets.kqsv4.KQcontext = &m->p->permanentsockets;
- m->p->permanentsockets.kqsv4.KQtask = "UDP packet reception";
+ m->p->permanentsockets.kqsv4.KQtask = "IPv4 UDP packet reception";
m->p->permanentsockets.sktv6 = -1;
m->p->permanentsockets.kqsv6.KQcallback = myKQSocketCallBack;
m->p->permanentsockets.kqsv6.KQcontext = &m->p->permanentsockets;
- m->p->permanentsockets.kqsv6.KQtask = "UDP packet reception";
+ m->p->permanentsockets.kqsv6.KQtask = "IPv6 UDP packet reception";
err = SetupSocket(&m->p->permanentsockets, MulticastDNSPort, AF_INET, mDNSNULL);
+ if (err) LogMsg("mDNSPlatformInit_setup: SetupSocket(AF_INET) failed error %d errno %d (%s)", err, errno, strerror(errno));
err = SetupSocket(&m->p->permanentsockets, MulticastDNSPort, AF_INET6, mDNSNULL);
+ if (err) LogMsg("mDNSPlatformInit_setup: SetupSocket(AF_INET6) failed error %d errno %d (%s)", err, errno, strerror(errno));
struct sockaddr_in s4;
socklen_t n4 = sizeof(s4);
@@ -9972,16 +10130,12 @@ mDNSlocal mStatus mDNSPlatformInit_setup(mDNS *const m)
err = WatchForNetworkChanges(m);
if (err) { LogMsg("mDNSPlatformInit_setup: WatchForNetworkChanges failed %d", err); return(err); }
-#if 0 // <rdar://problem/6751656>
- err = WatchForPMChanges(m);
- if (err) { LogMsg("mDNSPlatformInit_setup: WatchForPMChanges failed %d", err); return(err); }
-#endif
-
err = WatchForSysEvents(m);
if (err) { LogMsg("mDNSPlatformInit_setup: WatchForSysEvents failed %d", err); return(err); }
mDNSs32 utc = mDNSPlatformUTC();
m->SystemWakeOnLANEnabled = SystemWakeForNetworkAccess();
+ myGetIfAddrs(1);
UpdateInterfaceList(m, utc);
SetupActiveInterfaces(m, utc);
@@ -10069,7 +10223,6 @@ mDNSlocal mStatus mDNSPlatformInit_setup(mDNS *const m)
mDNSMacOSXUpdateEtcHosts(m);
SetupLocalHostRecords(m);
- CUPInit(m);
return(mStatus_NoError);
}
@@ -10303,6 +10456,42 @@ mDNSexport void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, co
}
}
+mDNSexport void mDNSPlatformPreventSleep(mDNS *const m, mDNSu32 timeout, const char *reason)
+{
+ if (m->p->IOPMAssertion)
+ {
+ LogSPS("Sleep Assertion is already being held. Will not attempt to get it again for %d seconds for %s", timeout, reason);
+ return;
+ }
+#ifdef kIOPMAssertionTypeNoIdleSleep
+
+#if TARGET_OS_EMBEDDED
+ if (!IsAppleTV())
+ return; // No need for maintenance wakes on non-AppleTV embedded devices.
+#endif
+
+ double timeoutVal = (double)timeout;
+ CFStringRef str = CFStringCreateWithCString(NULL, reason, kCFStringEncodingUTF8);
+ CFNumberRef Timeout_num = CFNumberCreate(NULL, kCFNumberDoubleType, &timeoutVal);
+ CFMutableDictionaryRef assertionProperties = CFDictionaryCreateMutable(NULL, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ if (IsAppleTV())
+ CFDictionarySetValue(assertionProperties, kIOPMAssertionTypeKey, kIOPMAssertPreventUserIdleSystemSleep);
+ else
+ CFDictionarySetValue(assertionProperties, kIOPMAssertionTypeKey, kIOPMAssertMaintenanceActivity);
+
+ CFDictionarySetValue(assertionProperties, kIOPMAssertionTimeoutKey, Timeout_num);
+ CFDictionarySetValue(assertionProperties, kIOPMAssertionNameKey, str);
+
+ IOPMAssertionCreateWithProperties(assertionProperties, (IOPMAssertionID *)&m->p->IOPMAssertion);
+ CFRelease(str);
+ CFRelease(Timeout_num);
+ CFRelease(assertionProperties);
+ LogSPS("Got an idle sleep assertion for %d seconds for %s", timeout, reason);
+#endif
+}
+
mDNSexport void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration)
{
mDNSu32 ifindex;
@@ -10330,6 +10519,10 @@ mDNSexport mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID)
|| (InterfaceID == mDNSInterface_Unicast))
return mDNSfalse;
+ // Compare to cached AWDL interface ID.
+ if (AWDLInterfaceID && (InterfaceID == AWDLInterfaceID))
+ return mDNStrue;
+
info = IfindexToInterfaceInfoOSX(&mDNSStorage, InterfaceID);
if (info == NULL)
{
@@ -10458,25 +10651,24 @@ mDNSexport void mDNSPlatformDispatchAsync(mDNS *const m, void *context, AsyncDis
// definitions for device-info record construction
#define DEVINFO_MODEL "model="
-#define DEVINFO_MODEL_LEN strlen(DEVINFO_MODEL)
+#define DEVINFO_MODEL_LEN sizeof_string(DEVINFO_MODEL)
#define OSX_VER "osxvers="
-#define OSX_VER_LEN strlen(OSX_VER)
+#define OSX_VER_LEN sizeof_string(OSX_VER)
#define VER_NUM_LEN 2 // 2 digits of version number added to base string
#define MODEL_COLOR "ecolor="
-#define MODEL_COLOR_LEN strlen(MODEL_COLOR)
-#define MODEL_RGB_VALUE_LEN strlen("255,255,255") // 'r,g,b'
+#define MODEL_COLOR_LEN sizeof_string(MODEL_COLOR)
+#define MODEL_RGB_VALUE_LEN sizeof_string("255,255,255") // 'r,g,b'
-// Bytes available in TXT record for model name after subtracting space for other
+// Bytes available in TXT record for model name after subtracting space for other
// fixed size strings and their length bytes.
#define MAX_MODEL_NAME_LEN (256 - (DEVINFO_MODEL_LEN + 1) - (OSX_VER_LEN + VER_NUM_LEN + 1) - (MODEL_COLOR_LEN + MODEL_RGB_VALUE_LEN + 1))
-mDNSlocal mDNSBool getModelIconColors(char *color)
+mDNSlocal mDNSu8 getModelIconColors(char *color)
{
- mDNSBool hasColor = mDNSfalse;
mDNSPlatformMemZero(color, MODEL_RGB_VALUE_LEN + 1);
-
+
#if !TARGET_OS_EMBEDDED && defined(kIOPlatformDeviceEnclosureColorKey)
mDNSu8 red = 0;
mDNSu8 green = 0;
@@ -10487,12 +10679,11 @@ mDNSlocal mDNSBool getModelIconColors(char *color)
if (kIOReturnSuccess == rGetDeviceColor)
{
// IOKit was able to get enclosure color for the current device.
- hasColor = true;
- snprintf(color, MODEL_RGB_VALUE_LEN + 1, "%d,%d,%d", red, green, blue);
+ return snprintf(color, MODEL_RGB_VALUE_LEN + 1, "%d,%d,%d", red, green, blue);
}
#endif // !TARGET_OS_EMBEDDED && defined(kIOPlatformDeviceEnclosureColorKey)
-
- return hasColor;
+
+ return 0;
}
@@ -10518,20 +10709,21 @@ mDNSexport mDNSu32 initializeDeviceInfoTXT(mDNS *m, mDNSu8 *ptr)
mDNSPlatformMemCopy(ptr, OSX_VER, OSX_VER_LEN);
ptr += OSX_VER_LEN;
// convert version number to ASCII, add 1 for terminating null byte written by snprintf()
+ // WARNING: This code assumes that OSXVers is always exactly two digits
snprintf(ver_num, VER_NUM_LEN + 1, "%d", OSXVers);
mDNSPlatformMemCopy(ptr, ver_num, VER_NUM_LEN);
ptr += VER_NUM_LEN;
-
+
char rgb[MODEL_RGB_VALUE_LEN + 1]; // RGB value + null written by snprintf
- if (getModelIconColors(rgb))
+ len = getModelIconColors(rgb);
+ if (len)
{
- len = strlen(rgb);
*ptr = MODEL_COLOR_LEN + len; // length byte
ptr++;
-
+
mDNSPlatformMemCopy(ptr, MODEL_COLOR, MODEL_COLOR_LEN);
ptr += MODEL_COLOR_LEN;
-
+
mDNSPlatformMemCopy(ptr, rgb, len);
ptr += len;
}