summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/mDNSMacOSX/mDNSMacOSX.c')
-rw-r--r--mDNSResponder/mDNSMacOSX/mDNSMacOSX.c280
1 files changed, 191 insertions, 89 deletions
diff --git a/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c b/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c
index 3bb4ec69..f64e28af 100644
--- a/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c
+++ b/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2018 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -86,22 +86,22 @@
#include <SystemConfiguration/SCPrivate.h>
#if TARGET_OS_IPHONE
-// For WiFiManagerClientRef etc, declarations.
-#include <MobileGestalt.h>
-#include <MobileWiFi/WiFiManagerClient.h>
+#include <MobileWiFi/WiFiManagerClient.h> // For WiFiManagerClientRef etc, declarations.
#include <dlfcn.h>
+#include <os/variant_private.h> // For os_variant_has_internal_diagnostics().
#endif // TARGET_OS_IPHONE
// Include definition of opaque_presence_indication for KEV_DL_NODE_PRESENCE handling logic.
#include <Kernel/IOKit/apple80211/apple80211_var.h>
#include <network_information.h> // for nwi_state
-#if APPLE_OSX_mDNSResponder
+#if MDNSRESPONDER_BTMM_SUPPORT
#include <AWACS.h>
+#endif
+
+#if APPLE_OSX_mDNSResponder
#include <ne_session.h> // for ne_session_set_socket_attributes()
-#else
-#define NO_AWACS 1
-#endif // APPLE_OSX_mDNSResponder
+#endif
#if APPLE_OSX_mDNSResponder && !TARGET_OS_EMBEDDED
#include <IOKit/platform/IOPlatformSupportPrivate.h>
@@ -153,9 +153,11 @@ static CFStringRef NetworkChangedKey_Computername;
static CFStringRef NetworkChangedKey_DNS;
static CFStringRef NetworkChangedKey_StateInterfacePrefix;
static CFStringRef NetworkChangedKey_DynamicDNS = CFSTR("Setup:/Network/DynamicDNS");
+static CFStringRef NetworkChangedKey_PowerSettings = CFSTR("State:/IOKit/PowerManagement/CurrentSettings");
+#if MDNSRESPONDER_BTMM_SUPPORT
static CFStringRef NetworkChangedKey_BackToMyMac = CFSTR("Setup:/Network/BackToMyMac");
static CFStringRef NetworkChangedKey_BTMMConnectivity = CFSTR("State:/Network/Connectivity");
-static CFStringRef NetworkChangedKey_PowerSettings = CFSTR("State:/IOKit/PowerManagement/CurrentSettings");
+#endif
static char HINFO_HWstring_buffer[32];
static char *HINFO_HWstring = "Device";
@@ -794,8 +796,8 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms
s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, sendto_errno, strerror(sendto_errno), (mDNSu32)(m->timenow));
if (!mDNSAddressIsAllDNSLinkGroup(dst))
{
- if (sendto_errno == EHOSTUNREACH) return(mStatus_HostUnreachErr);
- if (sendto_errno == EHOSTDOWN || sendto_errno == ENETDOWN || sendto_errno == ENETUNREACH) return(mStatus_TransientErr);
+ if ((sendto_errno == EHOSTUNREACH) || (sendto_errno == ENETUNREACH)) return(mStatus_HostUnreachErr);
+ if ((sendto_errno == EHOSTDOWN) || (sendto_errno == ENETDOWN)) return(mStatus_TransientErr);
}
// Don't report EHOSTUNREACH in the first three minutes after boot
// This is because mDNSResponder intentionally starts up early in the boot process (See <rdar://problem/3409090>)
@@ -3310,6 +3312,40 @@ mDNSlocal u_int64_t getExtendedFlags(char * ifa_name)
return ifr.ifr_eflags;
}
+#if TARGET_OS_OSX
+// IFRTYPE_FUNCTIONAL_INTCOPROC type interfaces on macOS do not support Bonjour discovery.
+mDNSlocal mDNSBool isCoprocessorInterface(int sockFD, char * ifa_name)
+{
+ struct ifreq ifr;
+
+ if (sockFD < 0)
+ {
+ LogMsg("isCoprocessorInterface: invalid socket FD passed: %d", sockFD);
+ return mDNSfalse;
+ }
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ strlcpy(ifr.ifr_name, ifa_name, sizeof(ifr.ifr_name));
+
+ if (ioctl(sockFD, SIOCGIFFUNCTIONALTYPE, (caddr_t)&ifr) == -1)
+ {
+ LogMsg("isCoprocessorInterface: SIOCGIFFUNCTIONALTYPE failed, errno = %d (%s)", errno, strerror(errno));
+ return mDNSfalse;
+ }
+
+ if (ifr.ifr_functional_type == IFRTYPE_FUNCTIONAL_INTCOPROC)
+ {
+ LogMsg("isCoprocessorInterface: %s marked as coprocessor interface", ifa_name);
+ return mDNStrue;
+ }
+ else
+ return mDNSfalse;
+}
+
+#else // TARGET_OS_OSX
+#define isCoprocessorInterface(A, B) mDNSfalse
+#endif // TARGET_OS_OSX
+
#if TARGET_OS_IPHONE
// Function pointers for the routines we use in the MobileWiFi framework.
@@ -3499,7 +3535,17 @@ mDNSlocal NetworkInterfaceInfoOSX *AddInterfaceToList(struct ifaddrs *ifa, mDNSs
// we get the corresponding name for the interface index on which the packet was received and check against
// the InterfaceList for a matching name. So, keep the name in sync
strlcpy((*p)->ifinfo.ifname, ifa->ifa_name, sizeof((*p)->ifinfo.ifname));
- (*p)->Exists = mDNStrue;
+
+ // Determine if multicast state has changed.
+ const mDNSBool txrx = MulticastInterface(*p);
+ if ((*p)->ifinfo.McastTxRx != txrx)
+ {
+ (*p)->ifinfo.McastTxRx = txrx;
+ (*p)->Exists = MulticastStateChanged; // State change; need to deregister and reregister this interface
+ }
+ else
+ (*p)->Exists = mDNStrue;
+
// If interface was not in getifaddrs list last time we looked, but it is now, update 'AppearanceTime' for this record
if ((*p)->LastSeen != utc) (*p)->AppearanceTime = utc;
@@ -3539,7 +3585,6 @@ mDNSlocal NetworkInterfaceInfoOSX *AddInterfaceToList(struct ifaddrs *ifa, mDNSs
// We can be configured to disable multicast advertisement, but we want to to support
// local-only services, which need a loopback address record.
i->ifinfo.Advertise = m->DivertMulticastAdvertisements ? ((ifa->ifa_flags & IFF_LOOPBACK) ? mDNStrue : mDNSfalse) : m->AdvertiseLocalAddresses;
- 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;
@@ -3566,6 +3611,7 @@ mDNSlocal NetworkInterfaceInfoOSX *AddInterfaceToList(struct ifaddrs *ifa, mDNSs
LogInfo("AddInterfaceToList: D2DInterface set for %s", ifa->ifa_name);
i->isExpensive = (eflags & IFEF_EXPENSIVE) ? mDNStrue: mDNSfalse;
+ i->isAWDL = (eflags & IFEF_AWDL) ? mDNStrue: mDNSfalse;
if (eflags & IFEF_AWDL)
{
// Set SupportsUnicastMDNSResponse false for the AWDL interface since unicast reserves
@@ -3590,6 +3636,8 @@ mDNSlocal NetworkInterfaceInfoOSX *AddInterfaceToList(struct ifaddrs *ifa, mDNSs
i->BPF_len = 0;
i->Registered = mDNSNULL;
+ // MulticastInterface() depends on the "m" and "ifa_flags" values being initialized above.
+ i->ifinfo.McastTxRx = MulticastInterface(i);
// Do this AFTER i->BSSID has been set up
i->ifinfo.NetWake = (eflags & IFEF_EXPENSIVE)? mDNSfalse : NetWakeInterface(i);
GetMAC(&i->ifinfo.MAC, scope_id);
@@ -4827,14 +4875,14 @@ mDNSlocal mStatus UpdateInterfaceList(mDNSs32 utc)
mDNSPlatformMemCopy(m->PrimaryMAC.b, sdl->sdl_data + sdl->sdl_nlen, 6);
}
- if (ifa->ifa_flags & IFF_UP && ifa->ifa_addr)
+ if (ifa->ifa_flags & IFF_UP && ifa->ifa_addr && !isCoprocessorInterface(InfoSocket, ifa->ifa_name))
if (ifa->ifa_addr->sa_family == AF_INET || ifa->ifa_addr->sa_family == AF_INET6)
{
if (!ifa->ifa_netmask)
{
mDNSAddr ip;
SetupAddr(&ip, ifa->ifa_addr);
- LogMsg("getifaddrs: ifa_netmask is NULL for %5s(%d) Flags %04X Family %2d %#a",
+ LogMsg("UpdateInterfaceList: ifa_netmask is NULL for %5s(%d) Flags %04X Family %2d %#a",
ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family, &ip);
}
// Apparently it's normal for the sa_family of an ifa_netmask to sometimes be zero, so we don't complain about that
@@ -4843,7 +4891,7 @@ mDNSlocal mStatus UpdateInterfaceList(mDNSs32 utc)
{
mDNSAddr ip;
SetupAddr(&ip, ifa->ifa_addr);
- LogMsg("getifaddrs ifa_netmask for %5s(%d) Flags %04X Family %2d %#a has different family: %d",
+ LogMsg("UpdateInterfaceList: ifa_netmask for %5s(%d) Flags %04X Family %2d %#a has different family: %d",
ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family, &ip, ifa->ifa_netmask->sa_family);
}
// Currently we use a few internal ones like mDNSInterfaceID_LocalOnly etc. that are negative values (0, -1, -2).
@@ -4900,19 +4948,6 @@ mDNSlocal mStatus UpdateInterfaceList(mDNSs32 utc)
if (!foundav4 && v4Loopback) AddInterfaceToList(v4Loopback, utc);
if (!foundav6 && v6Loopback) AddInterfaceToList(v6Loopback, utc);
- // Now the list is complete, set the McastTxRx setting for each interface.
- NetworkInterfaceInfoOSX *i;
- for (i = m->p->InterfaceList; i; i = i->next)
- if (i->Exists)
- {
- mDNSBool txrx = MulticastInterface(i);
- if (i->ifinfo.McastTxRx != txrx)
- {
- i->ifinfo.McastTxRx = txrx;
- i->Exists = MulticastStateChanged; // State change; need to deregister and reregister this interface
- }
- }
-
if (InfoSocket >= 0)
close(InfoSocket);
@@ -5234,7 +5269,7 @@ mDNSlocal int ClearInactiveInterfaces(mDNSs32 utc)
if (!i->Exists)
{
if (i->LastSeen == utc) i->LastSeen = utc - 1;
- mDNSBool delete = (NumCacheRecordsForInterfaceID(m, i->ifinfo.InterfaceID) == 0) && (utc - i->LastSeen >= 60);
+ const mDNSBool delete = (i->isAWDL || (NumCacheRecordsForInterfaceID(m, i->ifinfo.InterfaceID) == 0)) && (utc - i->LastSeen >= 60);
LogInfo("ClearInactiveInterfaces: %-13s %5s(%lu) %.6a InterfaceID %p(%p) %#a/%d Age %d%s", delete ? "Deleting" : "Holding",
i->ifinfo.ifname, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID, i,
&i->ifinfo.ip, CountMaskBits(&i->ifinfo.mask), utc - i->LastSeen,
@@ -5818,6 +5853,7 @@ mDNSlocal void SetupDDNSDomains(domainname *const fqdn, DNameListElem **RegDomai
}
CFRelease(ddnsdict);
}
+#if MDNSRESPONDER_BTMM_SUPPORT
if (RegDomains)
{
CFDictionaryRef btmm = SCDynamicStoreCopyValue(NULL, NetworkChangedKey_BackToMyMac);
@@ -5847,7 +5883,7 @@ mDNSlocal void SetupDDNSDomains(domainname *const fqdn, DNameListElem **RegDomai
CFRelease(btmm);
}
}
-
+#endif
}
// Returns mDNSfalse, if it does not set the configuration i.e., if the DNS configuration did not change
@@ -6141,7 +6177,7 @@ mDNSexport void mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const
}
}
-#if APPLE_OSX_mDNSResponder
+#if MDNSRESPONDER_BTMM_SUPPORT
#if !NO_AWACS
// checks whether a domain is present in Setup:/Network/BackToMyMac. Just because there is a key in the
@@ -6283,7 +6319,7 @@ mDNSlocal void UpdateBTMMRelayConnection(mDNS *const m)
else LogInfo("UpdateBTMMRelayConnection: Not calling AWS_Disconnect");
}
}
-#elif !TARGET_OS_EMBEDDED
+#else
mDNSlocal void UpdateBTMMRelayConnection(mDNS *const m)
{
(void) m; // Unused
@@ -6291,11 +6327,9 @@ mDNSlocal void UpdateBTMMRelayConnection(mDNS *const m)
}
#endif // ! NO_AWACS
-#if !TARGET_OS_EMBEDDED
mDNSlocal void ProcessConndConfigChanges(void);
-#endif
-#endif // APPLE_OSX_mDNSResponder
+#endif // MDNSRESPONDER_BTMM_SUPPORT
// MUST be called holding the lock
mDNSlocal void SetDomainSecrets_internal(mDNS *m)
@@ -6369,11 +6403,13 @@ mDNSlocal void SetDomainSecrets_internal(mDNS *m)
offset = 0;
if (!strncmp(stringbuf, dnsprefix, strlen(dnsprefix)))
offset = strlen(dnsprefix);
+#if MDNSRESPONDER_BTMM_SUPPORT
else if (!strncmp(stringbuf, btmmprefix, strlen(btmmprefix)))
{
AutoTunnel = mDNStrue;
offset = strlen(btmmprefix);
}
+#endif
domainname domain;
if (!MakeDomainNameFromDNSNameString(&domain, stringbuf + offset)) { LogMsg("SetDomainSecrets: bad key domain %s", stringbuf); continue; }
@@ -6555,7 +6591,9 @@ mDNSlocal void SetDomainSecrets_internal(mDNS *m)
}
UpdateAnonymousRacoonConfig(m); // Determine whether we need racoon to accept incoming connections
+#if MDNSRESPONDER_BTMM_SUPPORT
ProcessConndConfigChanges(); // Update AutoTunnelInnerAddress values and default ipsec policies as necessary
+#endif
}
#endif // APPLE_OSX_mDNSResponder
@@ -7236,8 +7274,9 @@ mDNSexport void RemoveAutoTunnel6Record(mDNS *const m)
if (info->AutoTunnel)
UpdateAutoTunnel6Record(m, info);
}
+#endif /* APPLE_OSX_mDNSResponder */
-#if !TARGET_OS_EMBEDDED
+#if MDNSRESPONDER_BTMM_SUPPORT
mDNSlocal mDNSBool IPv6AddressIsOnInterface(mDNSv6Addr ipv6Addr, char *ifname)
{
struct ifaddrs *ifa;
@@ -7474,8 +7513,7 @@ mDNSlocal void ProcessConndConfigChanges(void)
// If awacsd crashes or exits for some reason, restart it
UpdateBTMMRelayConnection(m);
}
-#endif // !TARGET_OS_EMBEDDED
-#endif /* APPLE_OSX_mDNSResponder */
+#endif // MDNSRESPONDER_BTMM_SUPPORT
mDNSlocal mDNSBool IsAppleNetwork(mDNS *const m)
{
@@ -7580,9 +7618,11 @@ mDNSexport void mDNSMacOSXNetworkChanged(void)
#if APPLE_OSX_mDNSResponder
#if !TARGET_OS_EMBEDDED
+#if MDNSRESPONDER_BTMM_SUPPORT
mDNS_Lock(m);
ProcessConndConfigChanges();
mDNS_Unlock(m);
+#endif
// Scan to find client tunnels whose questions have completed,
// but whose local inner/outer addresses have changed since the tunnel was set up
@@ -7806,14 +7846,18 @@ mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, v
//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
+ const int c = CFArrayGetCount(changedKeys); // Count changes
CFRange range = { 0, c };
- 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);
+ const int c_host = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_Hostnames ) != 0);
+ const int c_comp = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_Computername) != 0);
+ const int c_udns = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_DNS ) != 0);
+ const int c_ddns = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_DynamicDNS ) != 0);
+#if MDNSRESPONDER_BTMM_SUPPORT
+ const int c_btmm = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_BackToMyMac ) != 0);
+#else
+ const int c_btmm = 0;
+#endif
+ const int c_v4ll = ChangedKeysHaveIPv4LL(changedKeys);
int c_fast = 0;
// Do immediate network changed processing for "p2p*" interfaces and
@@ -7971,9 +8015,11 @@ mDNSlocal mStatus WatchForNetworkChanges(mDNS *const m)
CFArrayAppendValue(keys, NetworkChangedKey_Computername);
CFArrayAppendValue(keys, NetworkChangedKey_DNS);
CFArrayAppendValue(keys, NetworkChangedKey_DynamicDNS);
- CFArrayAppendValue(keys, NetworkChangedKey_BackToMyMac);
CFArrayAppendValue(keys, NetworkChangedKey_PowerSettings);
+#if MDNSRESPONDER_BTMM_SUPPORT
+ CFArrayAppendValue(keys, NetworkChangedKey_BackToMyMac);
CFArrayAppendValue(keys, NetworkChangedKey_BTMMConnectivity);
+#endif
CFArrayAppendValue(patterns, pattern1);
CFArrayAppendValue(patterns, pattern2);
CFArrayAppendValue(patterns, CFSTR("State:/Network/Interface/[^/]+/AirPort"));
@@ -8177,13 +8223,9 @@ mDNSlocal void removeCachedPeerRecords(mDNSu32 ifindex, mDNSAddr *ap, bool purge
// Handle KEV_DL_NODE_PRESENCE event.
mDNSlocal void nodePresence(struct kev_dl_node_presence * p)
{
- char buf[INET6_ADDRSTRLEN];
struct opaque_presence_indication *op = (struct opaque_presence_indication *) p->node_service_info;
- if (inet_ntop(AF_INET6, & p->sin6_node_address.sin6_addr, buf, sizeof(buf)))
- LogInfo("nodePresence: IPv6 address: %s, SUI %d", buf, op->SUI);
- else
- LogInfo("nodePresence: inet_ntop() error");
+ LogInfo("nodePresence: IPv6 address: %.16a, SUI %d", p->sin6_node_address.sin6_addr.s6_addr, op->SUI);
// AWDL will generate a KEV_DL_NODE_PRESENCE event with SSTH field of
// all zeroes when a node is present and has no services registered.
@@ -8203,17 +8245,11 @@ mDNSlocal void nodePresence(struct kev_dl_node_presence * p)
mDNSlocal void nodeAbsence(struct kev_dl_node_absence * p)
{
mDNSAddr peerAddr;
- char buf[INET6_ADDRSTRLEN];
-
- if (inet_ntop(AF_INET6, & p->sin6_node_address.sin6_addr, buf, sizeof(buf)))
- LogInfo("nodeAbsence: IPv6 address: %s", buf);
- else
- LogInfo("nodeAbsence: inet_ntop() error");
peerAddr.type = mDNSAddrType_IPv6;
peerAddr.ip.v6 = *(mDNSv6Addr*)&p->sin6_node_address.sin6_addr;
- LogInfo("nodeAbsence: immediately purge cached records from this peer");
+ LogInfo("nodeAbsence: immediately purge cached records from %.16a", p->sin6_node_address.sin6_addr.s6_addr);
removeCachedPeerRecords(p->sdl_node_address.sdl_index, & peerAddr, true);
}
@@ -8367,8 +8403,13 @@ mDNSlocal OSStatus KeychainChanged(SecKeychainEvent keychainEvent, SecKeychainCa
if (!err)
{
relevant = ((a->attr[0].length == 4 && (!strncasecmp(a->attr[0].data, "ddns", 4) || !strncasecmp(a->attr[0].data, "sndd", 4))) ||
- (a->attr[1].length >= mDNSPlatformStrLen(dnsprefix) && (!strncasecmp(a->attr[1].data, dnsprefix, mDNSPlatformStrLen(dnsprefix)))) ||
- (a->attr[1].length >= mDNSPlatformStrLen(btmmprefix) && (!strncasecmp(a->attr[1].data, btmmprefix, mDNSPlatformStrLen(btmmprefix)))));
+ (a->attr[1].length >= mDNSPlatformStrLen(dnsprefix) && (!strncasecmp(a->attr[1].data, dnsprefix, mDNSPlatformStrLen(dnsprefix)))));
+#if MDNSRESPONDER_BTMM_SUPPORT
+ if (!relevant && (a->attr[1].length >= mDNSPlatformStrLen(btmmprefix)) && !strncasecmp(a->attr[1].data, btmmprefix, mDNSPlatformStrLen(btmmprefix)))
+ {
+ relevant = mDNStrue;
+ }
+#endif
SecKeychainItemFreeAttributesAndData(a, NULL);
}
}
@@ -9419,36 +9460,13 @@ mDNSlocal void CreatePTRRecord(const domainname *domain)
// intentionally to avoid adding to the complexity of code handling /etc/hosts.
mDNSlocal void SetupLocalHostRecords(void)
{
- char buffer[MAX_REVERSE_MAPPING_NAME];
domainname name;
- int i;
- struct in6_addr addr;
- mDNSu8 *ptr = addr.__u6_addr.__u6_addr8;
- if (inet_pton(AF_INET, "127.0.0.1", &addr) == 1)
- {
- mDNS_snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d.in-addr.arpa.",
- ptr[3], ptr[2], ptr[1], ptr[0]);
- MakeDomainNameFromDNSNameString(&name, buffer);
- CreatePTRRecord(&name);
- }
- else LogMsg("SetupLocalHostRecords: ERROR!! inet_pton AF_INET failed");
+ MakeDomainNameFromDNSNameString(&name, "1.0.0.127.in-addr.arpa.");
+ CreatePTRRecord(&name);
- if (inet_pton(AF_INET6, "::1", &addr) == 1)
- {
- for (i = 0; i < 16; i++)
- {
- static const char hexValues[] = "0123456789ABCDEF";
- buffer[i * 4 ] = hexValues[ptr[15 - i] & 0x0F];
- buffer[i * 4 + 1] = '.';
- buffer[i * 4 + 2] = hexValues[ptr[15 - i] >> 4];
- buffer[i * 4 + 3] = '.';
- }
- mDNS_snprintf(&buffer[64], sizeof(buffer)-64, "ip6.arpa.");
- MakeDomainNameFromDNSNameString(&name, buffer);
- CreatePTRRecord(&name);
- }
- else LogMsg("SetupLocalHostRecords: ERROR!! inet_pton AF_INET6 failed");
+ MakeDomainNameFromDNSNameString(&name, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.");
+ CreatePTRRecord(&name);
}
#if APPLE_OSX_mDNSResponder // Don't compile for dnsextd target
@@ -9465,6 +9483,56 @@ mDNSlocal void setSameDomainLabelPointer(void);
// 6) client calls to enumerate domains now go over LocalOnly interface
// (!!!KRS may add outgoing interface in addition)
+#if TARGET_OS_IPHONE
+mDNSlocal mDNSBool IsAppleInternalBuild(void)
+{
+ return (os_variant_has_internal_diagnostics("com.apple.mDNSResponder") ? mDNStrue : mDNSfalse);
+}
+
+mDNSlocal mStatus RegisterLocalOnlyAddressRecord(const domainname *const name, mDNSu16 type, const void *rdata, mDNSu16 rdlength)
+{
+ switch(type)
+ {
+ case kDNSType_A:
+ if (rdlength != 4) return (mStatus_BadParamErr);
+ break;
+
+ case kDNSType_AAAA:
+ if (rdlength != 16) return (mStatus_BadParamErr);
+ break;
+
+ default:
+ return (mStatus_BadParamErr);
+ }
+
+ AuthRecord *rr = mallocL("etchosts", sizeof(*rr));
+ if (!rr) return (mStatus_NoMemoryErr);
+ mDNSPlatformMemZero(rr, sizeof(*rr));
+
+ mDNS_SetupResourceRecord(rr, NULL, mDNSInterface_LocalOnly, type, 1, kDNSRecordTypeKnownUnique, AuthRecordLocalOnly, FreeEtcHosts, NULL);
+ AssignDomainName(&rr->namestorage, name);
+ mDNSPlatformMemCopy(rr->resrec.rdata->u.data, rdata, rdlength);
+
+ const mStatus err = mDNS_Register_internal(&mDNSStorage, rr);
+ if (err)
+ {
+ LogMsg("RegisterLocalOnlyAddressRecord: mDNS_Register error %d registering %s", err, ARDisplayString(&mDNSStorage, rr));
+ freeL("etchosts", rr);
+ }
+ return (err);
+}
+
+mDNSlocal void RegisterLocalOnlyARecord(const domainname *const name, const mDNSv4Addr *const addr)
+{
+ RegisterLocalOnlyAddressRecord(name, kDNSType_A, addr->b, (mDNSu16)sizeof(mDNSv4Addr));
+}
+
+mDNSlocal void RegisterLocalOnlyAAAARecord(const domainname *const name, const mDNSv6Addr *const addr)
+{
+ RegisterLocalOnlyAddressRecord(name, kDNSType_AAAA, addr->b, (mDNSu16)sizeof(mDNSv6Addr));
+}
+#endif
+
mDNSlocal mStatus mDNSPlatformInit_setup(mDNS *const m)
{
mStatus err;
@@ -9694,7 +9762,41 @@ mDNSlocal mStatus mDNSPlatformInit_setup(mDNS *const m)
#endif
if (SSLqueue == mDNSNULL) LogMsg("dispatch_queue_create: SSL queue NULL");
- mDNSMacOSXUpdateEtcHosts(m);
+#if TARGET_OS_IPHONE
+ // On device OSes (iOS, tvOS, watchOS, etc.), ignore /etc/hosts unless the OS is an internal build. When the /etc/hosts
+ // file is ignored, LocalOnly auth records will be registered for localhost and broadcasthost addresses contained in the
+ // standard /etc/hosts file:
+ //
+ // 127.0.0.1 localhost
+ // 255.255.255.255 broadcasthost
+ // ::1 localhost
+
+ if (!IsAppleInternalBuild())
+ {
+ const domainname *const localHostName = (const domainname *) "\x9" "localhost";
+ const domainname *const broadcastHostName = (const domainname *) "\xd" "broadcasthost";
+ const mDNSv4Addr localHostV4 = { { 127, 0, 0, 1 } };
+ mDNSv6Addr localHostV6;
+
+ // Register localhost 127.0.0.1 A record.
+
+ RegisterLocalOnlyARecord(localHostName, &localHostV4);
+
+ // Register broadcasthost 255.255.255.255 A record.
+
+ RegisterLocalOnlyARecord(broadcastHostName, &onesIPv4Addr);
+
+ // Register localhost ::1 AAAA record.
+
+ mDNSPlatformMemZero(&localHostV6, sizeof(localHostV6));
+ localHostV6.b[15] = 1;
+ RegisterLocalOnlyAAAARecord(localHostName, &localHostV6);
+ }
+ else
+#endif
+ {
+ mDNSMacOSXUpdateEtcHosts(m);
+ }
SetupLocalHostRecords();
return(mStatus_NoError);