/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2002-2012 Apple Computer, 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.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// ***************************************************************************
// mDNSMacOSX.c:
// Supporting routines to run mDNS on a CFRunLoop platform
// ***************************************************************************

// For debugging, set LIST_ALL_INTERFACES to 1 to display all found interfaces,
// including ones that mDNSResponder chooses not to use.
#define LIST_ALL_INTERFACES 0

// For enabling AAAA records over IPv4. Setting this to 0 sends only
// A records over IPv4 and AAAA over IPv6. Setting this to 1 sends both
// AAAA and A records over both IPv4 and IPv6.
#define AAAA_OVER_V4 1

// In Mac OS X 10.4 and earlier, to reduce traffic, we would send and receive using IPv6 only on interfaces that had no routable
// IPv4 address. Having a routable IPv4 address assigned is a reasonable indicator of being on a large configured network,
// which means there's a good chance that most or all the other devices on that network should also have IPv4.
// By doing this we lost the ability to talk to true IPv6-only devices on that link, but we cut the packet rate in half.
// At that time, reducing the packet rate was more important than v6-only devices on a large configured network,
// so were willing to make that sacrifice.
// In Mac OS X 10.5, in 2007, two things have changed:
// 1. IPv6-only devices are starting to become more common, so we can't ignore them.
// 2. Other efficiency improvements in the code mean that crude hacks like this should no longer be necessary.

#define USE_V6_ONLY_WHEN_NO_ROUTABLE_V4 0

#include "mDNSEmbeddedAPI.h"        // Defines the interface provided to the client layer above
#include "DNSCommon.h"
#include "uDNS.h"
#include "mDNSMacOSX.h"             // Defines the specific types needed to run mDNS on this platform
#include "dns_sd.h"                 // For mDNSInterface_LocalOnly etc.
#include "PlatformCommon.h"
#include "uds_daemon.h"
#include "CryptoSupport.h"
#include "MobileInternetSharing_priv.h"

#include <stdio.h>
#include <stdarg.h>                 // For va_list support
#include <stdlib.h>                 // For arc4random
#include <net/if.h>
#include <net/if_types.h>           // For IFT_ETHER
#include <net/if_dl.h>
#include <net/bpf.h>                // For BIOCSETIF etc.
#include <sys/uio.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/event.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <time.h>                   // platform support for UTC time
#include <arpa/inet.h>              // for inet_aton
#include <pthread.h>
#include <netdb.h>                  // for getaddrinfo
#include <sys/sockio.h>             // for SIOCGIFEFLAGS

#include <netinet/in.h>             // For IP_RECVTTL
#ifndef IP_RECVTTL
#define IP_RECVTTL 24               // bool; receive reception TTL w/dgram
#endif

#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>

#if TARGET_OS_EMBEDDED
#define NO_SECURITYFRAMEWORK 1
#define NO_CFUSERNOTIFICATION 1
#endif

#ifndef NO_SECURITYFRAMEWORK
#include <Security/SecureTransport.h>
#include <Security/Security.h>
#endif /* NO_SECURITYFRAMEWORK */

#include <DebugServices.h>
#include "dnsinfo.h"

#include <ifaddrs.h>

#include <IOKit/IOKitLib.h>
#include <IOKit/IOMessage.h>

#if USE_IOPMCOPYACTIVEPMPREFERENCES
#include <IOKit/ps/IOPowerSources.h>
#include <IOKit/ps/IOPowerSourcesPrivate.h>
#endif

#include <mach/mach_error.h>
#include <mach/mach_port.h>
#include <mach/mach_time.h>
#include "helper.h"
#include "P2PPacketFilter.h"

#include <asl.h>

#if DNSINFO_VERSION >= 20110420
#include <SystemConfiguration/SCPrivate.h>
#else
#include <SystemConfiguration/SCDynamicStorePrivate.h>
#endif // DNSINFO_VERSION >= 20110420

// 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>

#if !NO_D2D
D2DStatus D2DInitialize(CFRunLoopRef runLoop, D2DServiceCallback serviceCallback, void* userData) __attribute__((weak_import));
D2DStatus D2DTerminate() __attribute__((weak_import));
D2DStatus D2DStartAdvertisingPair(const Byte *key, const size_t keySize, const Byte *value, const size_t valueSize) __attribute__((weak_import));
D2DStatus D2DStopAdvertisingPair(const Byte *key, const size_t keySize, const Byte *value, const size_t valueSize) __attribute__((weak_import));
D2DStatus D2DStartBrowsingForKey(const Byte *key, const size_t keySize) __attribute__((weak_import));
D2DStatus D2DStopBrowsingForKey(const Byte *key, const size_t keySize) __attribute__((weak_import));
void D2DStartResolvingPair(const Byte *key, const size_t keySize, const Byte *value, const size_t valueSize) __attribute__((weak_import));
void D2DStopResolvingPair(const Byte *key, const size_t keySize, const Byte *value, const size_t valueSize) __attribute__((weak_import));
D2DStatus D2DRetain(D2DServiceInstance instanceHandle, D2DTransportType transportType) __attribute__((weak_import));
D2DStatus D2DRelease(D2DServiceInstance instanceHandle, D2DTransportType transportType) __attribute__((weak_import));

#endif // ! NO_D2D

#else
#define NO_D2D 1
#define NO_AWACS 1
#endif // APPLE_OSX_mDNSResponder

#define kInterfaceSpecificOption "interface="

// cache the InterfaceID of the AWDL interface 
static mDNSInterfaceID AWDLInterfaceID;

// ***************************************************************************
// Globals

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - Globals
#endif

// By default we don't offer sleep proxy service
// If OfferSleepProxyService is set non-zero (typically via command-line switch),
// then we'll offer sleep proxy service on desktop Macs that are set to never sleep.
// We currently do not offer sleep proxy service on laptops, or on machines that are set to go to sleep.
mDNSexport int OfferSleepProxyService = 0;
mDNSexport int DisableSleepProxyClient = 0;
mDNSexport int UseInternalSleepProxy = 1;       // Set to non-zero to use internal (in-NIC) Sleep Proxy

mDNSexport int OSXVers, iOSVers;
mDNSexport int KQueueFD;

#ifndef NO_SECURITYFRAMEWORK
static CFArrayRef ServerCerts;
OSStatus SSLSetAllowAnonymousCiphers(SSLContextRef context, Boolean enable);
#endif /* NO_SECURITYFRAMEWORK */

static CFStringRef NetworkChangedKey_IPv4;
static CFStringRef NetworkChangedKey_IPv6;
static CFStringRef NetworkChangedKey_Hostnames;
static CFStringRef NetworkChangedKey_Computername;
static CFStringRef NetworkChangedKey_DNS;
static CFStringRef NetworkChangedKey_DynamicDNS       = CFSTR("Setup:/Network/DynamicDNS");
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");
static CFStringRef NetworkChangedKey_InternetSharing  = CFSTR("com.apple.InternetSharing");

static char HINFO_HWstring_buffer[32];
static char *HINFO_HWstring = "Device";
static int HINFO_HWstring_prefixlen = 6;

mDNSexport int WatchDogReportingThreshold = 250;

#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
dispatch_queue_t SSLqueue;
#endif

#if APPLE_OSX_mDNSResponder
static mDNSu8 SPMetricPortability   = 99;
static mDNSu8 SPMetricMarginalPower = 99;
static mDNSu8 SPMetricTotalPower    = 99;
static mDNSu8 SPMetricFeatures      = 1; /* The current version supports TCP Keep Alive Feature */
mDNSexport domainname ActiveDirectoryPrimaryDomain;
mDNSexport int ActiveDirectoryPrimaryDomainLabelCount;
mDNSexport mDNSAddr ActiveDirectoryPrimaryDomainServer;
#endif // APPLE_OSX_mDNSResponder

// Used by AutoTunnel
const char btmmprefix[] = "btmmdns:";
const char dnsprefix[] = "dns:";

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - D2D Support
#endif

#if !NO_D2D

// Name compression items for fake packet version number 1
static const mDNSu8 compression_packet_v1 = 0x01;

static DNSMessage compression_base_msg = { { {{0}}, {{0}}, 2, 0, 0, 0 }, "\x04_tcp\x05local\x00\x00\x0C\x00\x01\x04_udp\xC0\x11\x00\x0C\x00\x01" };
static mDNSu8 *const compression_limit = (mDNSu8 *) &compression_base_msg + sizeof(DNSMessage);
static mDNSu8 *const compression_lhs = (mDNSu8 *const) compression_base_msg.data + 27;

mDNSlocal void FreeD2DARElemCallback(mDNS *const m, AuthRecord *const rr, mStatus result);
mDNSlocal void PrintHex(mDNSu8 *data, mDNSu16 len);

typedef struct D2DRecordListElem
{
    struct D2DRecordListElem *next;
    AuthRecord               ar;
    D2DServiceInstance       instanceHandle;
    D2DTransportType         transportType;
} D2DRecordListElem;

static D2DRecordListElem *D2DRecords = NULL; // List of records returned with D2DServiceFound events

typedef struct D2DBrowseListElem
{
    struct D2DBrowseListElem *next;
    domainname name;
    mDNSu16 type;
    unsigned int refCount;
} D2DBrowseListElem;

D2DBrowseListElem* D2DBrowseList = NULL;

mDNSlocal mDNSu8 *putVal16(mDNSu8 *ptr, mDNSu16 val)
{
    ptr[0] = (mDNSu8)((val >> 8 ) & 0xFF);
    ptr[1] = (mDNSu8)((val      ) & 0xFF);
    return ptr + sizeof(mDNSu16);
}

mDNSlocal mDNSu8 *putVal32(mDNSu8 *ptr, mDNSu32 val)
{
    ptr[0] = (mDNSu8)((val >> 24) & 0xFF);
    ptr[1] = (mDNSu8)((val >> 16) & 0xFF);
    ptr[2] = (mDNSu8)((val >>  8) & 0xFF);
    ptr[3] = (mDNSu8)((val      ) & 0xFF);
    return ptr + sizeof(mDNSu32);
}

mDNSlocal void DomainnameToLower(const domainname * const in, domainname * const out)
{
    const mDNSu8 * const start = (const mDNSu8 * const)in;
    mDNSu8 *ptr = (mDNSu8*)start;
    while(*ptr)
    {
        mDNSu8 c = *ptr;
        out->c[ptr-start] = *ptr;
        ptr++;
        for (; c; c--,ptr++) out->c[ptr-start] = mDNSIsUpperCase(*ptr) ? (*ptr - 'A' + 'a') : *ptr;
    }
    out->c[ptr-start] = *ptr;
}

mDNSlocal mStatus DNSNameCompressionParseBytes(mDNS *const m, const mDNSu8 *const lhs, const mDNSu16 lhs_len, const mDNSu8 *const rhs, const mDNSu16 rhs_len, AuthRecord *rr)
{
    if (mDNS_LoggingEnabled)
    {
        LogInfo("%s", __func__);
        LogInfo("  Static Bytes: (%d bytes)", compression_lhs - (mDNSu8*)&compression_base_msg);
        PrintHex((mDNSu8*)&compression_base_msg, compression_lhs - (mDNSu8*)&compression_base_msg);
    }

    mDNSu8 *ptr = compression_lhs; // pointer to the end of our fake packet

    // Check to make sure we're not going to go past the end of the DNSMessage data
    // 7 = 2 for CLASS (-1 for our version) + 4 for TTL + 2 for RDLENGTH
    if (ptr + lhs_len - 7 + rhs_len >= compression_limit) return mStatus_NoMemoryErr;

    // Copy the LHS onto our fake wire packet
    mDNSPlatformMemCopy(ptr, lhs, lhs_len);
    ptr += lhs_len - 1;

    // Check the 'fake packet' version number, to ensure that we know how to decompress this data
    if (*ptr != compression_packet_v1) return mStatus_Incompatible;

    // two bytes of CLASS
    ptr = putVal16(ptr, kDNSClass_IN | kDNSClass_UniqueRRSet);

    // four bytes of TTL
    ptr = putVal32(ptr, 120);

    // Copy the RHS length into the RDLENGTH of our fake wire packet
    ptr = putVal16(ptr, rhs_len);

    // Copy the RHS onto our fake wire packet
    mDNSPlatformMemCopy(ptr, rhs, rhs_len);
    ptr += rhs_len;

    if (mDNS_LoggingEnabled)
    {
        LogInfo("  Our Bytes (%d bytes): ", ptr - compression_lhs);
        PrintHex(compression_lhs, ptr - compression_lhs);
    }

    ptr = (mDNSu8 *) GetLargeResourceRecord(m, &compression_base_msg, compression_lhs, ptr, mDNSInterface_Any, kDNSRecordTypePacketAns, &m->rec);
    if (!ptr || m->rec.r.resrec.RecordType == kDNSRecordTypePacketNegative)
    { LogMsg("DNSNameCompressionParseBytes: failed to get large RR"); m->rec.r.resrec.RecordType = 0; return mStatus_UnknownErr; }
    else LogInfo("DNSNameCompressionParseBytes: got rr: %s", CRDisplayString(m, &m->rec.r));

    mDNS_SetupResourceRecord(rr, mDNSNULL, mDNSInterface_P2P, m->rec.r.resrec.rrtype, 7200, kDNSRecordTypeShared, AuthRecordP2P, FreeD2DARElemCallback, NULL);
    AssignDomainName(&rr->namestorage, &m->rec.namestorage);
    rr->resrec.rdlength = m->rec.r.resrec.rdlength;
    rr->resrec.rdata->MaxRDLength = m->rec.r.resrec.rdlength;
    mDNSPlatformMemCopy(rr->resrec.rdata->u.data, m->rec.r.resrec.rdata->u.data, m->rec.r.resrec.rdlength);
    rr->resrec.namehash = DomainNameHashValue(rr->resrec.name);
    SetNewRData(&rr->resrec, mDNSNULL, 0);  // Sets rr->rdatahash for us

    m->rec.r.resrec.RecordType = 0; // Mark m->rec as no longer in use

    return mStatus_NoError;
}

mDNSlocal mDNSu8 * DNSNameCompressionBuildLHS(const domainname const *typeDomain, DNS_TypeValues qtype)
{
    mDNSu8 *ptr = putDomainNameAsLabels(&compression_base_msg, compression_lhs, compression_limit, typeDomain);
    if (!ptr) return ptr;
    *ptr = (qtype >> 8) & 0xff;
    ptr += 1;
    *ptr = qtype & 0xff;
    ptr += 1;
    *ptr = compression_packet_v1;
    return ptr + 1;
}

mDNSlocal mDNSu8 * DNSNameCompressionBuildRHS(mDNSu8 *start, const ResourceRecord *const resourceRecord)
{
    return putRData(&compression_base_msg, start, compression_limit, resourceRecord);
}

#define PRINT_DEBUG_BYTES_LIMIT 64  // set limit on number of record bytes printed for debugging

mDNSlocal void PrintHex(mDNSu8 *data, mDNSu16 len)
{
    mDNSu8 *end;
    char buffer[49] = {0};
    char *bufend = buffer + sizeof(buffer);

    if (len > PRINT_DEBUG_BYTES_LIMIT)
    {
        LogInfo(" (limiting debug output to %d bytes)", PRINT_DEBUG_BYTES_LIMIT);
        len = PRINT_DEBUG_BYTES_LIMIT;
    }
    end = data + len;

    while(data < end)
    {
        char *ptr = buffer;
        for(; data < end && ptr < bufend-1; ptr+=3,data++)
            mDNS_snprintf(ptr, bufend - ptr, "%02X ", *data);
        LogInfo("    %s", buffer);
    }
}

mDNSlocal void PrintHelper(const char *const tag, mDNSu8 *lhs, mDNSu16 lhs_len, mDNSu8 *rhs, mDNSu16 rhs_len)
{
    if (!mDNS_LoggingEnabled) return;

    LogInfo("%s:", tag);
    LogInfo("  LHS: (%d bytes)", lhs_len);
    PrintHex(lhs, lhs_len);

    if (!rhs) return;

    LogInfo("  RHS: (%d bytes)", rhs_len);
    PrintHex(rhs, rhs_len);
}

mDNSlocal void FreeD2DARElemCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
{
    (void)m;  // unused
    if (result == mStatus_MemFree)
    {
        D2DRecordListElem **ptr = &D2DRecords;
        D2DRecordListElem *tmp;
        while (*ptr && &(*ptr)->ar != rr) ptr = &(*ptr)->next;
        if (!*ptr) { LogMsg("FreeD2DARElemCallback: Could not find in D2DRecords: %s", ARDisplayString(m, rr)); return; }
        LogInfo("FreeD2DARElemCallback: Found in D2DRecords: %s", ARDisplayString(m, rr));
        tmp = *ptr;
        *ptr = (*ptr)->next;
        // Just because we stoppped browsing, doesn't mean we should tear down the PAN connection.
        mDNSPlatformMemFree(tmp);
    }
}

mDNSexport void external_connection_release(const domainname *instance)
{
    (void) instance;
    D2DRecordListElem *ptr = D2DRecords;

    for ( ; ptr ; ptr = ptr->next)
    {
        if ((ptr->ar.resrec.rrtype == kDNSServiceType_PTR) &&
             SameDomainName(&ptr->ar.rdatastorage.u.name, instance))
        {
            LogInfo("external_connection_release: Calling D2DRelease(instanceHandle = %p, transportType = %d", 
                ptr->instanceHandle,  ptr->transportType);
            if (D2DRelease) D2DRelease(ptr->instanceHandle, ptr->transportType);
        }
    }
}

mDNSlocal void xD2DClearCache(const domainname *regType)
{
    D2DRecordListElem *ptr = D2DRecords;
    for ( ; ptr ; ptr = ptr->next)
    {
        if (SameDomainName(&ptr->ar.namestorage, regType))
        {
            char buffer[MAX_ESCAPED_DOMAIN_NAME];
            mDNS_Deregister(&mDNSStorage, &ptr->ar);
            ConvertDomainNameToCString(regType, buffer);
            LogInfo("xD2DClearCache: Clearing cache record and deregistering %s", buffer);
        }
    }
}

mDNSlocal D2DBrowseListElem ** D2DFindInBrowseList(const domainname *const name, mDNSu16 type)
{
    D2DBrowseListElem **ptr = &D2DBrowseList;

    for ( ; *ptr; ptr = &(*ptr)->next)
        if ((*ptr)->type == type && SameDomainName(&(*ptr)->name, name))
            break;

    return ptr;
}

mDNSlocal unsigned int D2DBrowseListRefCount(const domainname *const name, mDNSu16 type)
{
    D2DBrowseListElem **ptr = D2DFindInBrowseList(name, type);
    return *ptr ? (*ptr)->refCount : 0;
}

mDNSlocal void D2DBrowseListRetain(const domainname *const name, mDNSu16 type)
{
    D2DBrowseListElem **ptr = D2DFindInBrowseList(name, type);

    if (!*ptr)
    {
        *ptr = mDNSPlatformMemAllocate(sizeof(**ptr));
        mDNSPlatformMemZero(*ptr, sizeof(**ptr));
        (*ptr)->type = type;
        AssignDomainName(&(*ptr)->name, name);
    }
    (*ptr)->refCount += 1;

    LogInfo("D2DBrowseListRetain: %##s %s refcount now %u", (*ptr)->name.c, DNSTypeName((*ptr)->type), (*ptr)->refCount);
}

mDNSlocal void D2DBrowseListRelease(const domainname *const name, mDNSu16 type)
{
    D2DBrowseListElem **ptr = D2DFindInBrowseList(name, type);

    if (!*ptr) { LogMsg("D2DBrowseListRelease: Didn't find %##s %s in list", name->c, DNSTypeName(type)); return; }

    (*ptr)->refCount -= 1;

    LogInfo("D2DBrowseListRelease: %##s %s refcount now %u", (*ptr)->name.c, DNSTypeName((*ptr)->type), (*ptr)->refCount);

    if (!(*ptr)->refCount)
    {
        D2DBrowseListElem *tmp = *ptr;
        *ptr = (*ptr)->next;
        mDNSPlatformMemFree(tmp);
    }
}

mDNSlocal mStatus xD2DParse(mDNS *const m, const mDNSu8 * const lhs, const mDNSu16 lhs_len, const mDNSu8 * const rhs, const mDNSu16 rhs_len, AuthRecord *rr)
{
    if (*(lhs + (lhs_len - 1)) == compression_packet_v1)
        return DNSNameCompressionParseBytes(m, lhs, lhs_len, rhs, rhs_len, rr);
    else
        return mStatus_Incompatible;
}

mDNSlocal void xD2DAddToCache(mDNS *const m, D2DStatus result, D2DServiceInstance instanceHandle, D2DTransportType transportType, const Byte *key, size_t keySize, const Byte *value, size_t valueSize)
{
    if (result == kD2DSuccess)
    {
        if ( key == NULL || value == NULL || keySize == 0 || valueSize == 0) { LogMsg("xD2DAddToCache: NULL Byte * passed in or length == 0"); return; }

        mStatus err;
        D2DRecordListElem *ptr = mDNSPlatformMemAllocate(sizeof(D2DRecordListElem) + (valueSize < sizeof(RData) ? 0 : valueSize - sizeof(RData)));

        if (ptr == NULL) { LogMsg("xD2DAddToCache: memory allocation failure"); return; }

        err = xD2DParse(m, (const mDNSu8 * const)key, (const mDNSu16)keySize, (const mDNSu8 * const)value, (const mDNSu16)valueSize, &ptr->ar);
        if (err)
        {
            LogMsg("xD2DAddToCache: xD2DParse returned error: %d", err);
            PrintHelper(__func__, (mDNSu8 *)key, (mDNSu16)keySize, (mDNSu8 *)value, (mDNSu16)valueSize);
            mDNSPlatformMemFree(ptr);
            return;
        }
        err = mDNS_Register(m, &ptr->ar);
        if (err)
        {
            LogMsg("xD2DAddToCache: mDNS_Register returned error %d for %s", err, ARDisplayString(m, &ptr->ar));
            mDNSPlatformMemFree(ptr);
            return;
        }

        LogInfo("xD2DAddToCache: mDNS_Register succeeded for %s", ARDisplayString(m, &ptr->ar));
        ptr->instanceHandle = instanceHandle;
        ptr->transportType = transportType;
        ptr->next = D2DRecords;
        D2DRecords = ptr;
    }
    else
        LogMsg("xD2DAddToCache: Unexpected result %d", result);
}

mDNSlocal D2DRecordListElem * xD2DFindInList(mDNS *const m, const Byte *const key, const size_t keySize, const Byte *const value, const size_t valueSize)
{
    D2DRecordListElem *ptr = D2DRecords;
    D2DRecordListElem *arptr;

    if ( key == NULL || value == NULL || keySize == 0 || valueSize == 0) { LogMsg("xD2DFindInList: NULL Byte * passed in or length == 0"); return NULL; }

    arptr = mDNSPlatformMemAllocate(sizeof(D2DRecordListElem) + (valueSize < sizeof(RData) ? 0 : valueSize - sizeof(RData)));
    if (arptr == NULL) { LogMsg("xD2DFindInList: memory allocation failure"); return NULL; }

    if (xD2DParse(m, (const mDNSu8 *const)key, (const mDNSu16)keySize, (const mDNSu8 *const)value, (const mDNSu16)valueSize, &arptr->ar) != mStatus_NoError)
    {
        LogMsg("xD2DFindInList: xD2DParse failed for key: %p (%u) value: %p (%u)", key, keySize, value, valueSize);
        mDNSPlatformMemFree(arptr);
        return NULL;
    }

    while (ptr)
    {
        if (IdenticalResourceRecord(&arptr->ar.resrec, &ptr->ar.resrec)) break;
        ptr = ptr->next;
    }

    if (!ptr) LogMsg("xD2DFindInList: Could not find in D2DRecords: %s", ARDisplayString(m, &arptr->ar));
    mDNSPlatformMemFree(arptr);
    return ptr;
}

mDNSlocal void xD2DRemoveFromCache(mDNS *const m, D2DStatus result, D2DServiceInstance instanceHandle, D2DTransportType transportType, const Byte *key, size_t keySize, const Byte *value, size_t valueSize)
{
    (void)transportType; // We don't care about this, yet.
    (void)instanceHandle; // We don't care about this, yet.

    if (result == kD2DSuccess)
    {
        D2DRecordListElem *ptr = xD2DFindInList(m, key, keySize, value, valueSize);
        if (ptr)
        {
            LogInfo("xD2DRemoveFromCache: Remove from cache: %s", ARDisplayString(m, &ptr->ar));
            mDNS_Deregister(m, &ptr->ar);
        }
    }
    else
        LogMsg("xD2DRemoveFromCache: Unexpected result %d", result);
}

mDNSlocal void xD2DServiceResolved(mDNS *const m, D2DStatus result, D2DServiceInstance instanceHandle, D2DTransportType transportType, const Byte *key, size_t keySize, const Byte *value, size_t valueSize)
{
    (void)m;
    (void)key;
    (void)keySize;
    (void)value;
    (void)valueSize;

    if (result == kD2DSuccess)
    {
        LogInfo("xD2DServiceResolved: Starting up PAN connection for %p", instanceHandle);
        if (D2DRetain) D2DRetain(instanceHandle, transportType);
    }
    else LogMsg("xD2DServiceResolved: Unexpected result %d", result);
}

mDNSlocal void xD2DRetainHappened(mDNS *const m, D2DStatus result, D2DServiceInstance instanceHandle, D2DTransportType transportType, const Byte *key, size_t keySize, const Byte *value, size_t valueSize)
{
    (void)m;
    (void)instanceHandle;
    (void)transportType;
    (void)key;
    (void)keySize;
    (void)value;
    (void)valueSize;

    if (result == kD2DSuccess) LogInfo("xD2DRetainHappened: Opening up PAN connection for %p", instanceHandle);
    else LogMsg("xD2DRetainHappened: Unexpected result %d", result);
}

mDNSlocal void xD2DReleaseHappened(mDNS *const m, D2DStatus result, D2DServiceInstance instanceHandle, D2DTransportType transportType, const Byte *key, size_t keySize, const Byte *value, size_t valueSize)
{
    (void)m;
    (void)instanceHandle;
    (void)transportType;
    (void)key;
    (void)keySize;
    (void)value;
    (void)valueSize;

    if (result == kD2DSuccess) LogInfo("xD2DReleaseHappened: Closing PAN connection for %p", instanceHandle);
    else LogMsg("xD2DReleaseHappened: Unexpected result %d", result);
}

mDNSlocal void xD2DServiceCallback(D2DServiceEvent event, D2DStatus result, D2DServiceInstance instanceHandle, D2DTransportType transportType, const Byte *key, size_t keySize, const Byte *value, size_t valueSize, void *userData)
{
    mDNS *m = (mDNS *) userData;
    const char *eventString = "unknown";

    KQueueLock(m);

    if (keySize   > 0xFFFF) LogMsg("xD2DServiceCallback: keySize too large: %u", keySize);
    if (valueSize > 0xFFFF) LogMsg("xD2DServiceCallback: valueSize too large: %u", valueSize);

    switch (event)
    {
    case D2DServiceFound:
        eventString = "D2DServiceFound";
        break;
    case D2DServiceLost:
        eventString = "D2DServiceLost";
        break;
    case D2DServiceResolved:
        eventString = "D2DServiceResolved";
        break;
    case D2DServiceRetained:
        eventString = "D2DServiceRetained";
        break;
    case D2DServiceReleased:
        eventString = "D2DServiceReleased";
        break;
    default:
        break;
    }

    LogInfo("xD2DServiceCallback: event=%s result=%d instanceHandle=%p transportType=%d LHS=%p (%u) RHS=%p (%u) userData=%p", eventString, result, instanceHandle, transportType, key, keySize, value, valueSize, userData);
    PrintHelper(__func__, (mDNSu8 *)key, (mDNSu16)keySize, (mDNSu8 *)value, (mDNSu16)valueSize);

    switch (event)
    {
    case D2DServiceFound:
        xD2DAddToCache(m, result, instanceHandle, transportType, key, keySize, value, valueSize);
        break;
    case D2DServiceLost:
        xD2DRemoveFromCache(m, result, instanceHandle, transportType, key, keySize, value, valueSize);
        break;
    case D2DServiceResolved:
        xD2DServiceResolved(m, result, instanceHandle, transportType, key, keySize, value, valueSize);
        break;
    case D2DServiceRetained:
        xD2DRetainHappened(m, result, instanceHandle, transportType, key, keySize, value, valueSize);
        break;
    case D2DServiceReleased:
        xD2DReleaseHappened(m, result, instanceHandle, transportType, key, keySize, value, valueSize);
        break;
    default:
        break;
    }

    // Need to tickle the main kqueue loop to potentially handle records we removed or added.
    KQueueUnlock(m, "xD2DServiceCallback");
}

// Map interface index and flags to a specific D2D transport type or D2DTransportMax if all plugins 
// should be called.
// When D2DTransportMax is returned, if a specific transport should not be called, *excludedTransportType 
// will be set to the excluded transport value, otherwise, it will be set to D2DTransportMax.
// If the return value is not D2DTransportMax, excludedTransportType is undefined.

mDNSlocal D2DTransportType xD2DInterfaceToTransportType(mDNSInterfaceID InterfaceID, DNSServiceFlags flags, D2DTransportType * excludedTransportType)
{
    NetworkInterfaceInfoOSX *info;

    // Default exludes the D2DAWDLTransport when D2DTransportMax is returned.
    *excludedTransportType = D2DAWDLTransport;

    // Call all D2D plugins when both kDNSServiceFlagsIncludeP2P and kDNSServiceFlagsIncludeAWDL are set.
    if ((flags & kDNSServiceFlagsIncludeP2P) && (flags & kDNSServiceFlagsIncludeAWDL))
    {
        LogInfo("xD2DInterfaceToTransportType: returning D2DTransportMax (including AWDL) since both kDNSServiceFlagsIncludeP2P and kDNSServiceFlagsIncludeAWDL are set");
        *excludedTransportType = D2DTransportMax;
        return D2DTransportMax;
    } 
    // Call all D2D plugins (exlcluding AWDL) when only kDNSServiceFlagsIncludeP2P is set.
    else if (flags & kDNSServiceFlagsIncludeP2P)
    {
        LogInfo("xD2DInterfaceToTransportType: returning D2DTransportMax (excluding AWDL) since only kDNSServiceFlagsIncludeP2P is set");
        return D2DTransportMax;
    }
    // Call AWDL D2D plugin when only kDNSServiceFlagsIncludeAWDL is set.
    else if (flags & kDNSServiceFlagsIncludeAWDL)
    {
        LogInfo("xD2DInterfaceToTransportType: returning D2DAWDLTransport since only kDNSServiceFlagsIncludeAWDL is set");
        return D2DAWDLTransport;
    }

    if (InterfaceID == mDNSInterface_P2P)
    {
        LogInfo("xD2DInterfaceToTransportType: returning D2DTransportMax (excluding AWDL) for interface index mDNSInterface_P2P");
        return D2DTransportMax; 
    }

    // Compare to cached AWDL interface ID.
    if (AWDLInterfaceID && (InterfaceID == AWDLInterfaceID))
    {
        LogInfo("xD2DInterfaceToTransportType: returning D2DAWDLTransport for interface index %d", InterfaceID);
        return D2DAWDLTransport;
    }

    info = IfindexToInterfaceInfoOSX(&mDNSStorage, InterfaceID);
    if (info == NULL)
    {
        LogInfo("xD2DInterfaceToTransportType: Invalid interface index %d", InterfaceID);
        return D2DTransportMax;
    }

    // Recognize AirDrop specific p2p* interface based on interface name.
    if (strncmp(info->ifinfo.ifname, "p2p", 3) == 0)
    {
        LogInfo("xD2DInterfaceToTransportType: returning D2DWifiPeerToPeerTransport for interface index %d", InterfaceID);
        return D2DWifiPeerToPeerTransport;
    }

    // Currently there is no way to identify Bluetooth interface by name,
    // since they use "en*" based name strings.

    LogInfo("xD2DInterfaceToTransportType: returning default D2DTransportMax for interface index %d", InterfaceID);
    return D2DTransportMax;
}

mDNSexport void external_start_browsing_for_service(mDNSInterfaceID InterfaceID, const domainname *const typeDomain, DNS_TypeValues qtype, DNSServiceFlags flags)
{
    domainname lower;

    if (qtype == kDNSServiceType_A || qtype == kDNSServiceType_AAAA)
    {
        LogInfo("external_start_browsing_for_service: ignoring address record");
        return;
    }

    DomainnameToLower(typeDomain, &lower);

    if (!D2DBrowseListRefCount(&lower, qtype))
    {
        D2DTransportType transportType, excludedTransport;

        LogInfo("external_start_browsing_for_service: Starting browse for: %##s %s", lower.c, DNSTypeName(qtype));
        mDNSu8 *end = DNSNameCompressionBuildLHS(&lower, qtype);
        PrintHelper(__func__, compression_lhs, end - compression_lhs, mDNSNULL, 0);

        transportType = xD2DInterfaceToTransportType(InterfaceID, flags, & excludedTransport);
        if (transportType == D2DTransportMax)
        {
            D2DTransportType i;
            for (i = 0; i < D2DTransportMax; i++)
            {
                if (i == excludedTransport) continue;
                if (D2DStartBrowsingForKeyOnTransport) D2DStartBrowsingForKeyOnTransport(compression_lhs, end - compression_lhs, i);
            }
        }
        else
        {
            if (D2DStartBrowsingForKeyOnTransport) D2DStartBrowsingForKeyOnTransport(compression_lhs, end - compression_lhs, transportType);
        }
    }
    D2DBrowseListRetain(&lower, qtype);
}

mDNSexport void external_stop_browsing_for_service(mDNSInterfaceID InterfaceID, const domainname *const typeDomain, DNS_TypeValues qtype, DNSServiceFlags flags)
{
    domainname lower;

    if (qtype == kDNSServiceType_A || qtype == kDNSServiceType_AAAA)
    {
        LogInfo("external_stop_browsing_for_service: ignoring address record");
        return;
    }

    DomainnameToLower(typeDomain, &lower);

    D2DBrowseListRelease(&lower, qtype);
    if (!D2DBrowseListRefCount(&lower, qtype))
    {
        D2DTransportType transportType, excludedTransport;

        LogInfo("external_stop_browsing_for_service: Stopping browse for: %##s %s", lower.c, DNSTypeName(qtype));
        mDNSu8 *end = DNSNameCompressionBuildLHS(&lower, qtype);
        PrintHelper(__func__, compression_lhs, end - compression_lhs, mDNSNULL, 0);

        transportType = xD2DInterfaceToTransportType(InterfaceID, flags, & excludedTransport);
        if (transportType == D2DTransportMax)
        {
            D2DTransportType i;
            for (i = 0; i < D2DTransportMax; i++)
            {
                if (i == excludedTransport) continue;
                if (D2DStopBrowsingForKeyOnTransport) D2DStopBrowsingForKeyOnTransport(compression_lhs, end - compression_lhs, i);
            }
        }
        else
        {
            if (D2DStopBrowsingForKeyOnTransport) D2DStopBrowsingForKeyOnTransport(compression_lhs, end - compression_lhs, transportType);
        }

        xD2DClearCache(&lower);
    }
}

mDNSexport void external_start_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags)
{
    domainname lower;
    mDNSu8 *rhs = NULL;
    mDNSu8 *end = NULL;
    D2DTransportType transportType, excludedTransport;
    DomainnameToLower(resourceRecord->name, &lower);

    LogInfo("external_start_advertising_service: %s", RRDisplayString(&mDNSStorage, resourceRecord));
    // For SRV records, update packet filter if p2p interface already exists, otherwise,
    // if will be updated when we get the KEV_DL_IF_ATTACHED event for the interface.
    if (resourceRecord->rrtype == kDNSType_SRV)
        mDNSUpdatePacketFilter(NULL);

    if (resourceRecord->rrtype == kDNSServiceType_A || resourceRecord->rrtype == kDNSServiceType_AAAA)
    {
        LogInfo("external_start_advertising_service: ignoring address record");
        return;
    }
    rhs = DNSNameCompressionBuildLHS(&lower, resourceRecord->rrtype);
    end = DNSNameCompressionBuildRHS(rhs, resourceRecord);
    PrintHelper(__func__, compression_lhs, rhs - compression_lhs, rhs, end - rhs);

    transportType = xD2DInterfaceToTransportType(resourceRecord->InterfaceID, flags, & excludedTransport);
    if (transportType == D2DTransportMax)
    {
        D2DTransportType i;
        for (i = 0; i < D2DTransportMax; i++)
        {
            if (i == excludedTransport) continue;
            if (D2DStartAdvertisingPairOnTransport) D2DStartAdvertisingPairOnTransport(compression_lhs, rhs - compression_lhs, rhs, end - rhs, i);
        }
    }
    else
    {
        if (D2DStartAdvertisingPairOnTransport) D2DStartAdvertisingPairOnTransport(compression_lhs, rhs - compression_lhs, rhs, end - rhs, transportType);
    }
}

mDNSexport void external_stop_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags)
{
    domainname lower;
    mDNSu8 *rhs = NULL;
    mDNSu8 *end = NULL;
    D2DTransportType transportType, excludedTransport;
    DomainnameToLower(resourceRecord->name, &lower);

    LogInfo("external_stop_advertising_service: %s", RRDisplayString(&mDNSStorage, resourceRecord));

    // For SRV records, update packet filter to to remove this port from list
    if (resourceRecord->rrtype == kDNSType_SRV)
        mDNSUpdatePacketFilter(resourceRecord);

    if (resourceRecord->rrtype == kDNSServiceType_A || resourceRecord->rrtype == kDNSServiceType_AAAA)
    {
        LogInfo("external_stop_advertising_service: ignoring address record");
        return;
    }
    rhs = DNSNameCompressionBuildLHS(&lower, resourceRecord->rrtype);
    end = DNSNameCompressionBuildRHS(rhs, resourceRecord);
    PrintHelper(__func__, compression_lhs, rhs - compression_lhs, rhs, end - rhs);

    transportType = xD2DInterfaceToTransportType(resourceRecord->InterfaceID, flags, & excludedTransport);
    if (transportType == D2DTransportMax)
    {
        D2DTransportType i;
        for (i = 0; i < D2DTransportMax; i++)
        {
            if (i == excludedTransport) continue;
            if (D2DStopAdvertisingPairOnTransport) D2DStopAdvertisingPairOnTransport(compression_lhs, rhs - compression_lhs, rhs, end - rhs, i);
        }
    }
    else
    {
        if (D2DStopAdvertisingPairOnTransport) D2DStopAdvertisingPairOnTransport(compression_lhs, rhs - compression_lhs, rhs, end - rhs, transportType);
    }
}

mDNSexport void external_start_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags)
{
    domainname lower;
    mDNSu8 *rhs = NULL;
    mDNSu8 *end = NULL;
    D2DTransportType transportType, excludedTransport;
    DomainnameToLower(SkipLeadingLabels(fqdn, 1), &lower);

    LogInfo("external_start_resolving_service: %##s", fqdn->c);
    rhs = DNSNameCompressionBuildLHS(&lower, kDNSType_PTR);
    end = putDomainNameAsLabels(&compression_base_msg, rhs, compression_limit, fqdn);
    PrintHelper(__func__, compression_lhs, rhs - compression_lhs, rhs, end - rhs);

    transportType = xD2DInterfaceToTransportType(InterfaceID, flags, & excludedTransport);
    if (transportType == D2DTransportMax)
    {
        D2DTransportType i;
        for (i = 0; i < D2DTransportMax; i++)
        {
            if (i == excludedTransport) continue;
            if (D2DStartResolvingPairOnTransport) D2DStartResolvingPairOnTransport(compression_lhs, rhs - compression_lhs, rhs, end - rhs, i);
        }
    }
    else
    {
        if (D2DStartResolvingPairOnTransport) D2DStartResolvingPairOnTransport(compression_lhs, rhs - compression_lhs, rhs, end - rhs, transportType);
    }
}

mDNSexport void external_stop_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags)
{
    domainname lower;
    mDNSu8 *rhs = NULL;
    mDNSu8 *end = NULL;
    D2DTransportType transportType, excludedTransport;
    DomainnameToLower(SkipLeadingLabels(fqdn, 1), &lower);

    LogInfo("external_stop_resolving_service: %##s", fqdn->c);
    rhs = DNSNameCompressionBuildLHS(&lower, kDNSType_PTR);
    end = putDomainNameAsLabels(&compression_base_msg, rhs, compression_limit, fqdn);
    PrintHelper(__func__, compression_lhs, rhs - compression_lhs, rhs, end - rhs);

    transportType = xD2DInterfaceToTransportType(InterfaceID, flags, & excludedTransport);
    if (transportType == D2DTransportMax)
    {
        D2DTransportType i;
        for (i = 0; i < D2DTransportMax; i++)
        {
            if (i == excludedTransport) continue;
            if (D2DStopResolvingPairOnTransport) D2DStopResolvingPairOnTransport(compression_lhs, rhs - compression_lhs, rhs, end - rhs, i);
        }
    }
    else
    {
        if (D2DStopResolvingPairOnTransport) D2DStopResolvingPairOnTransport(compression_lhs, rhs - compression_lhs, rhs, end - rhs, transportType);
    }
}

#elif APPLE_OSX_mDNSResponder

mDNSexport void external_start_browsing_for_service(mDNS *const m, const domainname *const type, DNS_TypeValues qtype, DNSServiceFlags flags) { (void)m; (void)type; (void)qtype; (void)flags;}
mDNSexport void external_stop_browsing_for_service(mDNS *const m, const domainname *const type, DNS_TypeValues qtype, DNSServiceFlags flags) { (void)m; (void)type; (void)qtype; (void)flags;}
mDNSexport void external_start_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags) { (void)resourceRecord; (void)flags;}
mDNSexport void external_stop_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags) { (void)resourceRecord; (void)flags;}
mDNSexport void external_start_resolving_service(const domainname *const fqdn, DNSServiceFlags flags)  { (void)fqdn; (void)flags;}
mDNSexport void external_stop_resolving_service(const domainname *const fqdn, DNSServiceFlags flags)  { (void)fqdn; (void)flags;}

#endif // ! NO_D2D

// ***************************************************************************
// Functions

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - Utility Functions
#endif

// We only attempt to send and receive multicast packets on interfaces that are
// (a) flagged as multicast-capable
// (b) *not* flagged as point-to-point (e.g. modem)
// Typically point-to-point interfaces are modems (including mobile-phone pseudo-modems), and we don't want
// 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.
#define MulticastInterface(i) (((i)->ifa_flags & IFF_MULTICAST) && !((i)->ifa_flags & IFF_POINTOPOINT))

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
    {
        // Determine if we're at Apple (17.*.*.*)
        NetworkInterfaceInfoOSX *i;
        for (i = mDNSStorage.p->InterfaceList; i; i = i->next)
            if (i->ifinfo.ip.type == mDNSAddrType_IPv4 && i->ifinfo.ip.ip.v4.b[0] == 17)
                break;
        if (!i) return; // If not at Apple, don't show the alert
    }
    #endif

    LogMsg("%s", title);
    LogMsg("%s", msg);
    // Display a notification to the user
    notifyCount++;

#ifndef NO_CFUSERNOTIFICATION
    mDNSNotify(title, msg);
#endif /* NO_CFUSERNOTIFICATION */
}

mDNSlocal struct ifaddrs *myGetIfAddrs(int refresh)
{
    static struct ifaddrs *ifa = NULL;

    if (refresh && ifa)
    {
        freeifaddrs(ifa);
        ifa = NULL;
    }

    if (ifa == NULL) getifaddrs(&ifa);
    return ifa;
}

// To match *either* a v4 or v6 instance of this interface name, pass AF_UNSPEC for type
mDNSlocal NetworkInterfaceInfoOSX *SearchForInterfaceByName(mDNS *const m, const char *ifname, int type)
{
    NetworkInterfaceInfoOSX *i;
    for (i = m->p->InterfaceList; i; i = i->next)
        if (i->Exists && !strcmp(i->ifinfo.ifname, ifname) &&
            ((type == AF_UNSPEC                                         ) ||
             (type == AF_INET  && i->ifinfo.ip.type == mDNSAddrType_IPv4) ||
             (type == AF_INET6 && i->ifinfo.ip.type == mDNSAddrType_IPv6))) return(i);
    return(NULL);
}

mDNSlocal int myIfIndexToName(u_short ifindex, char *name)
{
    struct ifaddrs *ifa;
    for (ifa = myGetIfAddrs(0); ifa; ifa = ifa->ifa_next)
        if (ifa->ifa_addr->sa_family == AF_LINK)
            if (((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index == ifindex)
            { strlcpy(name, ifa->ifa_name, IF_NAMESIZE); return 0; }
    return -1;
}

mDNSexport NetworkInterfaceInfoOSX *IfindexToInterfaceInfoOSX(const mDNS *const m, mDNSInterfaceID ifindex)
{
    mDNSu32 scope_id = (mDNSu32)(uintptr_t)ifindex;
    NetworkInterfaceInfoOSX *i;

    // Don't get tricked by inactive interfaces
    for (i = m->p->InterfaceList; i; i = i->next)
        if (i->Registered && i->scope_id == scope_id) return(i);

    return mDNSNULL;
}

mDNSexport mDNSInterfaceID mDNSPlatformInterfaceIDfromInterfaceIndex(mDNS *const m, mDNSu32 ifindex)
{
    if (ifindex == kDNSServiceInterfaceIndexLocalOnly) return(mDNSInterface_LocalOnly);
    if (ifindex == kDNSServiceInterfaceIndexP2P      ) return(mDNSInterface_P2P);
    if (ifindex == kDNSServiceInterfaceIndexAny      ) return(mDNSNULL);

    NetworkInterfaceInfoOSX* ifi = IfindexToInterfaceInfoOSX(m, (mDNSInterfaceID)(uintptr_t)ifindex);
    if (!ifi)
    {
        // Not found. Make sure our interface list is up to date, then try again.
        LogInfo("mDNSPlatformInterfaceIDfromInterfaceIndex: InterfaceID for interface index %d not found; Updating interface list", ifindex);
        mDNSMacOSXNetworkChanged(m);
        ifi = IfindexToInterfaceInfoOSX(m, (mDNSInterfaceID)(uintptr_t)ifindex);
    }

    if (!ifi) return(mDNSNULL);

    return(ifi->ifinfo.InterfaceID);
}


mDNSexport mDNSu32 mDNSPlatformInterfaceIndexfromInterfaceID(mDNS *const m, mDNSInterfaceID id, mDNSBool suppressNetworkChange)
{
    NetworkInterfaceInfoOSX *i;
    if (id == mDNSInterface_LocalOnly) return(kDNSServiceInterfaceIndexLocalOnly);
    if (id == mDNSInterface_P2P      ) return(kDNSServiceInterfaceIndexP2P);
    if (id == mDNSInterface_Any      ) return(0);

    mDNSu32 scope_id = (mDNSu32)(uintptr_t)id;

    // Don't use i->Registered here, because we DO want to find inactive interfaces, which have no Registered set
    for (i = m->p->InterfaceList; i; i = i->next)
        if (i->scope_id == scope_id) return(i->scope_id);

    // If we are supposed to suppress network change, return "id" back
    if (suppressNetworkChange) return scope_id;

    // Not found. Make sure our interface list is up to date, then try again.
    LogInfo("Interface index for InterfaceID %p not found; Updating interface list", id);
    mDNSMacOSXNetworkChanged(m);
    for (i = m->p->InterfaceList; i; i = i->next)
        if (i->scope_id == scope_id) return(i->scope_id);

    return(0);
}

#if APPLE_OSX_mDNSResponder
mDNSexport void mDNSASLLog(uuid_t *uuid, const char *subdomain, const char *result, const char *signature, const char *fmt, ...)
{
    if (OSXVers < OSXVers_10_6_SnowLeopard) return; // Only do ASL on Mac OS X 10.6 and later (not on iOS)

    static char buffer[512];
    aslmsg asl_msg = asl_new(ASL_TYPE_MSG);

    if (!asl_msg)   { LogMsg("mDNSASLLog: asl_new failed"); return; }
    if (uuid)
    {
        char uuidStr[37];
        uuid_unparse(*uuid, uuidStr);
        asl_set     (asl_msg, "com.apple.message.uuid", uuidStr);
    }

    static char domainBase[] = "com.apple.mDNSResponder.%s";
    mDNS_snprintf   (buffer, sizeof(buffer), domainBase, subdomain);
    asl_set         (asl_msg, "com.apple.message.domain", buffer);

    if (result) asl_set(asl_msg, "com.apple.message.result", result);
    if (signature) asl_set(asl_msg, "com.apple.message.signature", signature);

    va_list ptr;
    va_start(ptr,fmt);
    mDNS_vsnprintf(buffer, sizeof(buffer), fmt, ptr);
    va_end(ptr);

    int old_filter = asl_set_filter(NULL,ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));
    asl_log(NULL, asl_msg, ASL_LEVEL_DEBUG, "%s", buffer);
    asl_set_filter(NULL, old_filter);
    asl_free(asl_msg);
}
#endif // APPLE_OSX_mDNSResponder

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - UDP & TCP send & receive
#endif

mDNSlocal mDNSBool AddrRequiresPPPConnection(const struct sockaddr *addr)
{
    mDNSBool result = mDNSfalse;
    SCNetworkConnectionFlags flags;
#if DNSINFO_VERSION >= 20110420
    CFDataRef remote_addr;
    CFMutableDictionaryRef options;
#endif // DNSINFO_VERSION >= 20110420
    SCNetworkReachabilityRef ReachRef = NULL;

#if DNSINFO_VERSION >= 20110420
    options = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    remote_addr = CFDataCreate(NULL, (const UInt8 *)addr, addr->sa_len);
    CFDictionarySetValue(options, kSCNetworkReachabilityOptionRemoteAddress, remote_addr);
    CFDictionarySetValue(options, kSCNetworkReachabilityOptionServerBypass, kCFBooleanTrue);
    ReachRef = SCNetworkReachabilityCreateWithOptions(kCFAllocatorDefault, options);
    CFRelease(options);
    CFRelease(remote_addr);
    if (!ReachRef) { LogMsg("ERROR: RequiresConnection - SCNetworkReachabilityCreateWithOptions"); goto end; }
#else
    ReachRef = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, addr);
    if (!ReachRef) { LogMsg("ERROR: RequiresConnection - SCNetworkReachabilityCreateWithAddress"); goto end; }
#endif //  DNSINFO_VERSION >= 20110420
    if (!SCNetworkReachabilityGetFlags(ReachRef, &flags)) { LogMsg("ERROR: AddrRequiresPPPConnection - SCNetworkReachabilityGetFlags"); goto end; }
    result = flags & kSCNetworkFlagsConnectionRequired;

end:
    if (ReachRef) CFRelease(ReachRef);
    return result;
}

// Set traffic class for socket
mDNSlocal void setTrafficClass(int socketfd, mDNSBool useBackgroundTrafficClass)
{
    int traffic_class;

    if (useBackgroundTrafficClass)
        traffic_class = SO_TC_BK_SYS;
    else
        traffic_class = SO_TC_CTL;

    (void) setsockopt(socketfd, SOL_SOCKET, SO_TRAFFIC_CLASS, (void *)&traffic_class, sizeof(traffic_class));
}

// Note: If InterfaceID is NULL, it means, "send this packet through our anonymous unicast socket"
// Note: If InterfaceID is non-NULL it means, "send this packet through our port 5353 socket on the specified interface"
// OR send via our primary v4 unicast socket
// UPDATE: The UDPSocket *src parameter now allows the caller to specify the source socket
mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
                                       mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, 
                                       mDNSIPPort dstPort, mDNSBool useBackgroundTrafficClass)
{
    NetworkInterfaceInfoOSX *info = mDNSNULL;
    struct sockaddr_storage to;
    int s = -1, err;
    mStatus result = mStatus_NoError;

    if (InterfaceID)
    {
        info = IfindexToInterfaceInfoOSX(m, InterfaceID);
        if (info == NULL)
        {
            // We may not have registered interfaces with the "core" as we may not have
            // seen any interface notifications yet. This typically happens during wakeup
            // where we might try to send DNS requests (non-SuppressUnusable questions internal
            // to mDNSResponder) before we receive network notifications.
            LogInfo("mDNSPlatformSendUDP: Invalid interface index %p", InterfaceID);
            return mStatus_BadParamErr;
        }
    }

    char *ifa_name = InterfaceID ? info->ifinfo.ifname : "unicast";

    if (dst->type == mDNSAddrType_IPv4)
    {
        struct sockaddr_in *sin_to = (struct sockaddr_in*)&to;
        sin_to->sin_len            = sizeof(*sin_to);
        sin_to->sin_family         = AF_INET;
        sin_to->sin_port           = dstPort.NotAnInteger;
        sin_to->sin_addr.s_addr    = dst->ip.v4.NotAnInteger;
        s = (src ? src->ss : m->p->permanentsockets).sktv4;

        if (info)   // Specify outgoing interface
        {
            if (!mDNSAddrIsDNSMulticast(dst))
            {
                #ifdef IP_BOUND_IF
                if (info->scope_id == 0)
                    LogInfo("IP_BOUND_IF socket option not set -- info %p (%s) scope_id is zero", info, ifa_name);
                else
                    setsockopt(s, IPPROTO_IP, IP_BOUND_IF, &info->scope_id, sizeof(info->scope_id));
                #else
                {
                    static int displayed = 0;
                    if (displayed < 1000)
                    {
                        displayed++;
                        LogInfo("IP_BOUND_IF socket option not defined -- cannot specify interface for unicast packets");
                    }
                }
                #endif
            }
            else
                #ifdef IP_MULTICAST_IFINDEX
            {
                err = setsockopt(s, IPPROTO_IP, IP_MULTICAST_IFINDEX, &info->scope_id, sizeof(info->scope_id));
                // We get an error when we compile on a machine that supports this option and run the binary on
                // a different machine that does not support it
                if (err < 0)
                {
                    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)
                        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)
                    LogMsg("setsockopt - IP_MULTICAST_IF error %.4a %d errno %d (%s)", &info->ifa_v4addr, err, errno, strerror(errno));

            }
                #endif
        }
    }
#ifndef NO_IPV6
    else if (dst->type == mDNSAddrType_IPv6)
    {
        struct sockaddr_in6 *sin6_to = (struct sockaddr_in6*)&to;
        sin6_to->sin6_len            = sizeof(*sin6_to);
        sin6_to->sin6_family         = AF_INET6;
        sin6_to->sin6_port           = dstPort.NotAnInteger;
        sin6_to->sin6_flowinfo       = 0;
        sin6_to->sin6_addr           = *(struct in6_addr*)&dst->ip.v6;
        sin6_to->sin6_scope_id       = info ? info->scope_id : 0;
        s = (src ? src->ss : m->p->permanentsockets).sktv6;
        if (info && mDNSAddrIsDNSMulticast(dst))    // Specify outgoing interface
        {
            err = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &info->scope_id, sizeof(info->scope_id));
            if (err < 0)
            {
                char name[IFNAMSIZ];
                if (if_indextoname(info->scope_id, name) != NULL)
                    LogMsg("setsockopt - IPV6_MULTICAST_IF error %d errno %d (%s)", err, errno, strerror(errno));
                else
                    LogInfo("setsockopt - IPV6_MUTLICAST_IF scopeid %d, not a valid interface", info->scope_id);
            }
        }
    }
#endif
    else
    {
        LogMsg("mDNSPlatformSendUDP: dst is not an IPv4 or IPv6 address!");
#if ForceAlerts
        *(long*)0 = 0;
#endif
        return mStatus_BadParamErr;
    }

    if (s >= 0)
        verbosedebugf("mDNSPlatformSendUDP: sending on InterfaceID %p %5s/%ld to %#a:%d skt %d",
                      InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s);
    else
        verbosedebugf("mDNSPlatformSendUDP: NOT sending on InterfaceID %p %5s/%ld (socket of this type not available)",
                      InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort));

    // Note: When sending, mDNSCore may often ask us to send both a v4 multicast packet and then a v6 multicast packet
    // If we don't have the corresponding type of socket available, then return mStatus_Invalid
    if (s < 0) return(mStatus_Invalid);

    // switch to background traffic class for this message if requested
    if (useBackgroundTrafficClass)
        setTrafficClass(s, useBackgroundTrafficClass);

    err = sendto(s, msg, (UInt8*)end - (UInt8*)msg, 0, (struct sockaddr *)&to, to.ss_len);

    // set traffic class back to default value
    if (useBackgroundTrafficClass)
        setTrafficClass(s, mDNSfalse);

    if (err < 0)
    {
        static int MessageCount = 0;
        // Don't report EHOSTDOWN (i.e. ARP failure), ENETDOWN, or no route to host for unicast destinations
        if (!mDNSAddressIsAllDNSLinkGroup(dst))
            if (errno == EHOSTDOWN || errno == ENETDOWN || errno == EHOSTUNREACH || errno == ENETUNREACH) 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>)
        // 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 == 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));
        else
        {
            MessageCount += 100;
            if (MessageCount < 1000)  // Cap and ensure NO spamming of LogMsgs
                LogMsg("mDNSPlatformSendUDP: sendto(%d) failed to send packet on InterfaceID %p %5s/%d to %#a:%d skt %d error %d errno %d (%s) %lu MessageCount is %d",
                       s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, errno, strerror(errno), (mDNSu32)(m->timenow), MessageCount);
            else  // If logging is enabled, remove the cap and log aggressively
                LogInfo("mDNSPlatformSendUDP: sendto(%d) failed to send packet on InterfaceID %p %5s/%d to %#a:%d skt %d error %d errno %d (%s) %lu MessageCount is %d",
                        s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, errno, strerror(errno), (mDNSu32)(m->timenow), MessageCount);
        }

        result = mStatus_UnknownErr;
    }

#ifdef IP_BOUND_IF
    if (dst->type == mDNSAddrType_IPv4 && info && !mDNSAddrIsDNSMulticast(dst))
    {
        static const mDNSu32 ifindex = 0;
        setsockopt(s, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex));
    }
#endif

    return(result);
}

mDNSlocal ssize_t myrecvfrom(const int s, void *const buffer, const size_t max,
                             struct sockaddr *const from, size_t *const fromlen, mDNSAddr *dstaddr, char ifname[IF_NAMESIZE], mDNSu8 *ttl)
{
    static unsigned int numLogMessages = 0;
    struct iovec databuffers = { (char *)buffer, max };
    struct msghdr msg;
    ssize_t n;
    struct cmsghdr *cmPtr;
    char ancillary[1024];

    *ttl = 255;  // If kernel fails to provide TTL data (e.g. Jaguar doesn't) then assume the TTL was 255 as it should be

    // Set up the message
    msg.msg_name       = (caddr_t)from;
    msg.msg_namelen    = *fromlen;
    msg.msg_iov        = &databuffers;
    msg.msg_iovlen     = 1;
    msg.msg_control    = (caddr_t)&ancillary;
    msg.msg_controllen = sizeof(ancillary);
    msg.msg_flags      = 0;

    // Receive the data
    n = recvmsg(s, &msg, 0);
    if (n<0)
    {
        if (errno != EWOULDBLOCK && numLogMessages++ < 100) LogMsg("mDNSMacOSX.c: recvmsg(%d) returned error %d errno %d", s, n, errno);
        return(-1);
    }
    if (msg.msg_controllen < (int)sizeof(struct cmsghdr))
    {
        if (numLogMessages++ < 100) LogMsg("mDNSMacOSX.c: recvmsg(%d) returned %d msg.msg_controllen %d < sizeof(struct cmsghdr) %lu",
                                           s, n, msg.msg_controllen, sizeof(struct cmsghdr));
        return(-1);
    }
    if (msg.msg_flags & MSG_CTRUNC)
    {
        if (numLogMessages++ < 100) LogMsg("mDNSMacOSX.c: recvmsg(%d) msg.msg_flags & MSG_CTRUNC", s);
        return(-1);
    }

    *fromlen = msg.msg_namelen;

    // Parse each option out of the ancillary data.
    for (cmPtr = CMSG_FIRSTHDR(&msg); cmPtr; cmPtr = CMSG_NXTHDR(&msg, cmPtr))
    {
        // debugf("myrecvfrom cmsg_level %d cmsg_type %d", cmPtr->cmsg_level, cmPtr->cmsg_type);
        if (cmPtr->cmsg_level == IPPROTO_IP && cmPtr->cmsg_type == IP_RECVDSTADDR)
        {
            dstaddr->type = mDNSAddrType_IPv4;
            dstaddr->ip.v4 = *(mDNSv4Addr*)CMSG_DATA(cmPtr);
            //LogMsg("mDNSMacOSX.c: recvmsg IP_RECVDSTADDR %.4a", &dstaddr->ip.v4);
        }
        if (cmPtr->cmsg_level == IPPROTO_IP && cmPtr->cmsg_type == IP_RECVIF)
        {
            struct sockaddr_dl *sdl = (struct sockaddr_dl *)CMSG_DATA(cmPtr);
            if (sdl->sdl_nlen < IF_NAMESIZE)
            {
                mDNSPlatformMemCopy(ifname, sdl->sdl_data, sdl->sdl_nlen);
                ifname[sdl->sdl_nlen] = 0;
                // debugf("IP_RECVIF sdl_index %d, sdl_data %s len %d", sdl->sdl_index, ifname, sdl->sdl_nlen);
            }
        }
        if (cmPtr->cmsg_level == IPPROTO_IP && cmPtr->cmsg_type == IP_RECVTTL)
            *ttl = *(u_char*)CMSG_DATA(cmPtr);
        if (cmPtr->cmsg_level == IPPROTO_IPV6 && cmPtr->cmsg_type == IPV6_PKTINFO)
        {
            struct in6_pktinfo *ip6_info = (struct in6_pktinfo*)CMSG_DATA(cmPtr);
            dstaddr->type = mDNSAddrType_IPv6;
            dstaddr->ip.v6 = *(mDNSv6Addr*)&ip6_info->ipi6_addr;
            myIfIndexToName(ip6_info->ipi6_ifindex, ifname);
        }
        if (cmPtr->cmsg_level == IPPROTO_IPV6 && cmPtr->cmsg_type == IPV6_HOPLIMIT)
            *ttl = *(int*)CMSG_DATA(cmPtr);
    }

    return(n);
}

mDNSlocal void myKQSocketCallBack(int s1, short filter, void *context)
{
    KQSocketSet *const ss = (KQSocketSet *)context;
    mDNS *const m = ss->m;
    int err = 0, count = 0, closed = 0;

    if (filter != EVFILT_READ)
        LogMsg("myKQSocketCallBack: Why is filter %d not EVFILT_READ (%d)?", filter, EVFILT_READ);

    if (s1 != ss->sktv4
#ifndef NO_IPV6
        && s1 != ss->sktv6
#endif
        )
    {
        LogMsg("myKQSocketCallBack: native socket %d", s1);
        LogMsg("myKQSocketCallBack: sktv4 %d", ss->sktv4);
#ifndef NO_IPV6
        LogMsg("myKQSocketCallBack: sktv6 %d", ss->sktv6);
#endif
    }

    while (!closed)
    {
        mDNSAddr senderAddr, destAddr;
        mDNSIPPort senderPort;
        struct sockaddr_storage from;
        size_t fromlen = sizeof(from);
        char packetifname[IF_NAMESIZE] = "";
        mDNSu8 ttl;
        err = myrecvfrom(s1, &m->imsg, sizeof(m->imsg), (struct sockaddr *)&from, &fromlen, &destAddr, packetifname, &ttl);
        if (err < 0) break;

        count++;
        if (from.ss_family == AF_INET)
        {
            struct sockaddr_in *s = (struct sockaddr_in*)&from;
            senderAddr.type = mDNSAddrType_IPv4;
            senderAddr.ip.v4.NotAnInteger = s->sin_addr.s_addr;
            senderPort.NotAnInteger = s->sin_port;
            //LogInfo("myKQSocketCallBack received IPv4 packet from %#-15a to %#-15a on skt %d %s", &senderAddr, &destAddr, s1, packetifname);
        }
        else if (from.ss_family == AF_INET6)
        {
            struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&from;
            senderAddr.type = mDNSAddrType_IPv6;
            senderAddr.ip.v6 = *(mDNSv6Addr*)&sin6->sin6_addr;
            senderPort.NotAnInteger = sin6->sin6_port;
            //LogInfo("myKQSocketCallBack received IPv6 packet from %#-15a to %#-15a on skt %d %s", &senderAddr, &destAddr, s1, packetifname);
        }
        else
        {
            LogMsg("myKQSocketCallBack from is unknown address family %d", from.ss_family);
            return;
        }

        // Note: When handling multiple packets in a batch, MUST reset InterfaceID before handling each packet
        mDNSInterfaceID InterfaceID = mDNSNULL;
        //NetworkInterfaceInfo *intf = m->HostInterfaces;
        //while (intf && strcmp(intf->ifname, packetifname)) intf = intf->next;

        NetworkInterfaceInfoOSX *intf = m->p->InterfaceList;
        while (intf && strcmp(intf->ifinfo.ifname, packetifname)) intf = intf->next;

        // When going to sleep we deregister all our interfaces, but if the machine
        // takes a few seconds to sleep we may continue to receive multicasts
        // during that time, which would confuse mDNSCoreReceive, because as far
        // as it's concerned, we should have no active interfaces any more.
        // Hence we ignore multicasts for which we can find no matching InterfaceID.
        if (intf) InterfaceID = intf->ifinfo.InterfaceID;
        else if (mDNSAddrIsDNSMulticast(&destAddr)) continue;

//		LogMsg("myKQSocketCallBack got packet from %#a to %#a on interface %#a/%s",
//			&senderAddr, &destAddr, &ss->info->ifinfo.ip, ss->info->ifinfo.ifname);

        // mDNSCoreReceive may close the socket we're reading from.  We must break out of our
        // loop when that happens, or we may try to read from an invalid FD.  We do this by
        // setting the closeFlag pointer in the socketset, so CloseSocketSet can inform us
        // if it closes the socketset.
        ss->closeFlag = &closed;

        mDNSCoreReceive(m, &m->imsg, (unsigned char*)&m->imsg + err, &senderAddr, senderPort, &destAddr, ss->port, InterfaceID);

        // if we didn't close, we can safely dereference the socketset, and should to
        // reset the closeFlag, since it points to something on the stack
        if (!closed) ss->closeFlag = mDNSNULL;
    }

    if (err < 0 && (errno != EWOULDBLOCK || count == 0))
    {
        // Something is busted here.
        // kqueue says there is a packet, but myrecvfrom says there is not.
        // Try calling select() to get another opinion.
        // Find out about other socket parameter that can help understand why select() says the socket is ready for read
        // All of this is racy, as data may have arrived after the call to select()
        static unsigned int numLogMessages = 0;
        int save_errno = errno;
        int so_error = -1;
        int so_nread = -1;
        int fionread = -1;
        socklen_t solen = sizeof(int);
        fd_set readfds;
        struct timeval timeout;
        int selectresult;
        FD_ZERO(&readfds);
        FD_SET(s1, &readfds);
        timeout.tv_sec  = 0;
        timeout.tv_usec = 0;
        selectresult = select(s1+1, &readfds, NULL, NULL, &timeout);
        if (getsockopt(s1, SOL_SOCKET, SO_ERROR, &so_error, &solen) == -1)
            LogMsg("myKQSocketCallBack getsockopt(SO_ERROR) error %d", errno);
        if (getsockopt(s1, SOL_SOCKET, SO_NREAD, &so_nread, &solen) == -1)
            LogMsg("myKQSocketCallBack getsockopt(SO_NREAD) error %d", errno);
        if (ioctl(s1, FIONREAD, &fionread) == -1)
            LogMsg("myKQSocketCallBack ioctl(FIONREAD) error %d", errno);
        if (numLogMessages++ < 100)
            LogMsg("myKQSocketCallBack recvfrom skt %d error %d errno %d (%s) select %d (%spackets waiting) so_error %d so_nread %d fionread %d count %d",
                   s1, err, save_errno, strerror(save_errno), selectresult, FD_ISSET(s1, &readfds) ? "" : "*NO* ", so_error, so_nread, fionread, count);
        if (numLogMessages > 5)
            NotifyOfElusiveBug("Flaw in Kernel (select/recvfrom mismatch)",
                               "Congratulations, you've reproduced an elusive bug.\r"
                               "Please contact the current assignee of <rdar://problem/3375328>.\r"
                               "Alternatively, you can send email to radar-3387020@group.apple.com. (Note number is different.)\r"
                               "If possible, please leave your machine undisturbed so that someone can come to investigate the problem.");

        sleep(1);       // After logging this error, rate limit so we don't flood syslog
    }
}

// TCP socket support

typedef enum
{
    handshake_required,
    handshake_in_progress,
    handshake_completed,
    handshake_to_be_closed
} handshakeStatus;

struct TCPSocket_struct
{
    TCPSocketFlags flags;       // MUST BE FIRST FIELD -- mDNSCore expects every TCPSocket_struct to begin with TCPSocketFlags flags
    TCPConnectionCallback callback;
    int fd;
    KQueueEntry *kqEntry;
    KQSocketSet ss;
#ifndef NO_SECURITYFRAMEWORK
    SSLContextRef tlsContext;
    pthread_t handshake_thread;
#endif /* NO_SECURITYFRAMEWORK */
    domainname hostname;
    void *context;
    mDNSBool setup;
    mDNSBool connected;
    handshakeStatus handshake;
    mDNS *m; // So we can call KQueueLock from the SSLHandshake thread
    mStatus err;
};

mDNSlocal void doTcpSocketCallback(TCPSocket *sock)
{
    mDNSBool c = !sock->connected;
    sock->connected = mDNStrue;
    sock->callback(sock, sock->context, c, sock->err);
    // Note: the callback may call CloseConnection here, which frees the context structure!
}

#ifndef NO_SECURITYFRAMEWORK

mDNSlocal OSStatus tlsWriteSock(SSLConnectionRef connection, const void *data, size_t *dataLength)
{
    int ret = send(((TCPSocket *)connection)->fd, data, *dataLength, 0);
    if (ret >= 0 && (size_t)ret < *dataLength) { *dataLength = ret; return(errSSLWouldBlock); }
    if (ret >= 0)                              { *dataLength = ret; return(noErr); }
    *dataLength = 0;
    if (errno == EAGAIN                      ) return(errSSLWouldBlock);
    if (errno == ENOENT                      ) return(errSSLClosedGraceful);
    if (errno == EPIPE || errno == ECONNRESET) return(errSSLClosedAbort);
    LogMsg("ERROR: tlsWriteSock: %d error %d (%s)\n", ((TCPSocket *)connection)->fd, errno, strerror(errno));
    return(errSSLClosedAbort);
}

mDNSlocal OSStatus tlsReadSock(SSLConnectionRef connection, void *data, size_t *dataLength)
{
    int ret = recv(((TCPSocket *)connection)->fd, data, *dataLength, 0);
    if (ret > 0 && (size_t)ret < *dataLength) { *dataLength = ret; return(errSSLWouldBlock); }
    if (ret > 0)                              { *dataLength = ret; return(noErr); }
    *dataLength = 0;
    if (ret == 0 || errno == ENOENT    ) return(errSSLClosedGraceful);
    if (            errno == EAGAIN    ) return(errSSLWouldBlock);
    if (            errno == ECONNRESET) return(errSSLClosedAbort);
    LogMsg("ERROR: tlsSockRead: error %d (%s)\n", errno, strerror(errno));
    return(errSSLClosedAbort);
}

mDNSlocal OSStatus tlsSetupSock(TCPSocket *sock, mDNSBool server)
{
    char domname_cstr[MAX_ESCAPED_DOMAIN_NAME];

    mStatus err = SSLNewContext(server, &sock->tlsContext);
    if (err) { LogMsg("ERROR: tlsSetupSock: SSLNewContext failed with error code: %d", err); return(err); }

    err = SSLSetIOFuncs(sock->tlsContext, tlsReadSock, tlsWriteSock);
    if (err) { LogMsg("ERROR: tlsSetupSock: SSLSetIOFuncs failed with error code: %d", err); return(err); }

    err = SSLSetConnection(sock->tlsContext, (SSLConnectionRef) sock);
    if (err) { LogMsg("ERROR: tlsSetupSock: SSLSetConnection failed with error code: %d", err); return(err); }

    // Instead of listing all the acceptable ciphers, we just disable the bad ciphers. It does not disable
    // all the bad ciphers like RC4_MD5, but it assumes that the servers don't offer them.
    err = SSLSetAllowAnonymousCiphers(sock->tlsContext, 0);
    if (err) { LogMsg("ERROR: tlsSetupSock: SSLSetAllowAnonymousCiphers failed with error code: %d", err); return(err); }

    // We already checked for NULL in hostname and this should never happen. Hence, returning -1
    // (error not in OSStatus space) is okay.
    if (!sock->hostname.c[0]) {LogMsg("ERROR: tlsSetupSock: hostname NULL"); return -1; }

    ConvertDomainNameToCString(&sock->hostname, domname_cstr);
    err = SSLSetPeerDomainName(sock->tlsContext, domname_cstr, strlen(domname_cstr));
    if (err) { LogMsg("ERROR: tlsSetupSock: SSLSetPeerDomainname: %s failed with error code: %d", domname_cstr, err); return(err); }

    return(err);
}

#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
mDNSlocal void doSSLHandshake(void *ctx)
{
    TCPSocket *sock = (TCPSocket*)ctx;
    mStatus err = SSLHandshake(sock->tlsContext);

    //Can't have multiple threads in mDNS core. When MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM is
    //defined, KQueueLock is a noop. Hence we need to serialize here
    //
    //NOTE: We just can't serialize doTcpSocketCallback alone on the main queue.
    //We need the rest of the logic also. Otherwise, we can enable the READ
    //events below, dispatch a doTcpSocketCallback on the main queue. Assume it is
    //ConnFailed which means we are going to free the tcpInfo. While it
    //is waiting to be dispatched, another read event can come into tcpKQSocketCallback
    //and potentially call doTCPCallback with error which can close the fd and free the
    //tcpInfo. Later when the thread gets dispatched it will crash because the tcpInfo
    //is already freed.

    dispatch_async(dispatch_get_main_queue(), ^{

                       LogInfo("doSSLHandshake %p: got lock", sock); // Log *after* we get the lock

                       if (sock->handshake == handshake_to_be_closed)
                       {
                           LogInfo("SSLHandshake completed after close");
                           mDNSPlatformTCPCloseConnection(sock);
                       }
                       else
                       {
                           if (sock->fd != -1) KQueueSet(sock->fd, EV_ADD, EVFILT_READ, sock->kqEntry);
                           else LogMsg("doSSLHandshake: sock->fd is -1");

                           if (err == errSSLWouldBlock)
                               sock->handshake = handshake_required;
                           else
                           {
                               if (err)
                               {
                                   LogMsg("SSLHandshake failed: %d%s", err, err == errSSLPeerInternalError ? " (server busy)" : "");
                                   SSLDisposeContext(sock->tlsContext);
                                   sock->tlsContext = NULL;
                               }

                               sock->err = err ? mStatus_ConnFailed : 0;
                               sock->handshake = handshake_completed;

                               LogInfo("doSSLHandshake: %p calling doTcpSocketCallback fd %d", sock, sock->fd);
                               doTcpSocketCallback(sock);
                           }
                       }

                       LogInfo("SSLHandshake %p: dropping lock for fd %d", sock, sock->fd);
                       return;
                   });
}
#else
mDNSlocal void *doSSLHandshake(void *ctx)
{
    // Warning: Touching sock without the kqueue lock!
    // We're protected because sock->handshake == handshake_in_progress
    TCPSocket *sock = (TCPSocket*)ctx;
    mDNS * const m = sock->m; // Get m now, as we may free sock if marked to be closed while we're waiting on SSLHandshake
    mStatus err = SSLHandshake(sock->tlsContext);

    KQueueLock(m);
    debugf("doSSLHandshake %p: got lock", sock); // Log *after* we get the lock

    if (sock->handshake == handshake_to_be_closed)
    {
        LogInfo("SSLHandshake completed after close");
        mDNSPlatformTCPCloseConnection(sock);
    }
    else
    {
        if (sock->fd != -1) KQueueSet(sock->fd, EV_ADD, EVFILT_READ, sock->kqEntry);
        else LogMsg("doSSLHandshake: sock->fd is -1");

        if (err == errSSLWouldBlock)
            sock->handshake = handshake_required;
        else
        {
            if (err)
            {
                LogMsg("SSLHandshake failed: %d%s", err, err == errSSLPeerInternalError ? " (server busy)" : "");
                SSLDisposeContext(sock->tlsContext);
                sock->tlsContext = NULL;
            }

            sock->err = err ? mStatus_ConnFailed : 0;
            sock->handshake = handshake_completed;

            debugf("doSSLHandshake: %p calling doTcpSocketCallback fd %d", sock, sock->fd);
            doTcpSocketCallback(sock);
        }
    }

    debugf("SSLHandshake %p: dropping lock for fd %d", sock, sock->fd);
    KQueueUnlock(m, "doSSLHandshake");
    return NULL;
}
#endif

mDNSlocal mStatus spawnSSLHandshake(TCPSocket* sock)
{
    debugf("spawnSSLHandshake %p: entry", sock);
    mStatus err;

    if (sock->handshake != handshake_required) LogMsg("spawnSSLHandshake: handshake status not required: %d", sock->handshake);
    sock->handshake = handshake_in_progress;
    KQueueSet(sock->fd, EV_DELETE, EVFILT_READ, sock->kqEntry);
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM

    // Dispatch it on a separate serial queue to avoid deadlocks with threads running on main queue
    dispatch_async(SSLqueue, ^{doSSLHandshake(sock);});
    err = 0;
#else
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    err = pthread_create(&sock->handshake_thread, &attr, doSSLHandshake, sock);
    pthread_attr_destroy(&attr);
    if (err)
    {
        LogMsg("Could not start SSLHandshake thread: (%d) %s", err, strerror(err));
        sock->handshake = handshake_completed;
        sock->err = err;
        KQueueSet(sock->fd, EV_ADD, EVFILT_READ, sock->kqEntry);
    }
#endif
    debugf("spawnSSLHandshake %p: done for %d", sock, sock->fd);
    return err;
}

#endif /* NO_SECURITYFRAMEWORK */

mDNSlocal void tcpKQSocketCallback(__unused int fd, short filter, void *context)
{
    TCPSocket *sock = context;
    sock->err = mStatus_NoError;

    //if (filter == EVFILT_READ ) LogMsg("myKQSocketCallBack: tcpKQSocketCallback %d is EVFILT_READ", filter);
    //if (filter == EVFILT_WRITE) LogMsg("myKQSocketCallBack: tcpKQSocketCallback %d is EVFILT_WRITE", filter);
    // EV_ONESHOT doesn't seem to work, so we add the filter with EV_ADD, and explicitly delete it here with EV_DELETE
    if (filter == EVFILT_WRITE) KQueueSet(sock->fd, EV_DELETE, EVFILT_WRITE, sock->kqEntry);

    if (sock->flags & kTCPSocketFlags_UseTLS)
    {
#ifndef NO_SECURITYFRAMEWORK
        if (!sock->setup) { sock->setup = mDNStrue; tlsSetupSock(sock, mDNSfalse); }

        if (sock->handshake == handshake_required) { if (spawnSSLHandshake(sock) == 0) return;}
        else if (sock->handshake == handshake_in_progress || sock->handshake == handshake_to_be_closed) return;
        else if (sock->handshake != handshake_completed)
        {
            if (!sock->err) sock->err = mStatus_UnknownErr;
            LogMsg("tcpKQSocketCallback called with unexpected SSLHandshake status: %d", sock->handshake);
        }
#else
        sock->err = mStatus_UnsupportedErr;
#endif /* NO_SECURITYFRAMEWORK */
    }

    doTcpSocketCallback(sock);
}

#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
mDNSexport int KQueueSet(int fd, u_short flags, short filter, KQueueEntry *const entryRef)
{
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_source_t source;
    if (flags == EV_DELETE)
    {
        if (filter == EVFILT_READ)
        {
            dispatch_source_cancel(entryRef->readSource);
            dispatch_release(entryRef->readSource);
            entryRef->readSource = mDNSNULL;
            debugf("KQueueSet: source cancel for read %p, %p", entryRef->readSource, entryRef->writeSource);
        }
        else if (filter == EVFILT_WRITE)
        {
            dispatch_source_cancel(entryRef->writeSource);
            dispatch_release(entryRef->writeSource);
            entryRef->writeSource = mDNSNULL;
            debugf("KQueueSet: source cancel for write %p, %p", entryRef->readSource, entryRef->writeSource);
        }
        else
            LogMsg("KQueueSet: ERROR: Wrong filter value %d for EV_DELETE", filter);
        return 0;
    }
    if (flags != EV_ADD) LogMsg("KQueueSet: Invalid flags %d", flags);

    if (filter == EVFILT_READ)
    {
        source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, fd, 0, queue);
    }
    else if (filter == EVFILT_WRITE)
    {
        source = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, fd, 0, queue);
    }
    else
    {
        LogMsg("KQueueSet: ERROR: Wrong filter value %d for EV_ADD", filter);
        return -1;
    }
    if (!source) return -1;
    dispatch_source_set_event_handler(source, ^{

                                          mDNSs32 stime = mDNSPlatformRawTime();
                                          entryRef->KQcallback(fd, filter, entryRef->KQcontext);
                                          mDNSs32 etime = mDNSPlatformRawTime();
                                          if (etime - stime >= WatchDogReportingThreshold)
                                              LogInfo("KQEntryCallback Block: WARNING: took %dms to complete", etime - stime);

                                          // Trigger the event delivery to the application. Even though we trigger the
                                          // event completion after handling every event source, these all will hopefully
                                          // get merged
                                          TriggerEventCompletion();

                                      });
    dispatch_source_set_cancel_handler(source, ^{
                                           if (entryRef->fdClosed)
                                           {
                                               //LogMsg("CancelHandler: closing fd %d", fd);
                                               close(fd);
                                           }
                                       });
    dispatch_resume(source);
    if (filter == EVFILT_READ)
        entryRef->readSource = source;
    else
        entryRef->writeSource = source;

    return 0;
}

mDNSexport void KQueueLock(mDNS *const m)
{
    (void)m; //unused
}
mDNSexport void KQueueUnlock(mDNS *const m, const char const *task)
{
    (void)m; //unused
    (void)task; //unused
}
#else
mDNSexport int KQueueSet(int fd, u_short flags, short filter, const KQueueEntry *const entryRef)
{
    struct kevent new_event;
    EV_SET(&new_event, fd, filter, flags, 0, 0, (void*)entryRef);
    return (kevent(KQueueFD, &new_event, 1, NULL, 0, NULL) < 0) ? errno : 0;
}

mDNSexport void KQueueLock(mDNS *const m)
{
    pthread_mutex_lock(&m->p->BigMutex);
    m->p->BigMutexStartTime = mDNSPlatformRawTime();
}

mDNSexport void KQueueUnlock(mDNS *const m, const char const *task)
{
    mDNSs32 end = mDNSPlatformRawTime();
    (void)task;
    if (end - m->p->BigMutexStartTime >= WatchDogReportingThreshold)
        LogInfo("WARNING: %s took %dms to complete", task, end - m->p->BigMutexStartTime);

    pthread_mutex_unlock(&m->p->BigMutex);

    char wake = 1;
    if (send(m->p->WakeKQueueLoopFD, &wake, sizeof(wake), 0) == -1)
        LogMsg("ERROR: KQueueWake: send failed with error code: %d (%s)", errno, strerror(errno));
}
#endif

mDNSexport void mDNSPlatformCloseFD(KQueueEntry *kq, int fd)
{
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
        (void) fd; //unused
    if (kq->readSource)
    {
        dispatch_source_cancel(kq->readSource);
        kq->readSource = mDNSNULL;
    }
    if (kq->writeSource)
    {
        dispatch_source_cancel(kq->writeSource);
        kq->writeSource = mDNSNULL;
    }
    // Close happens in the cancellation handler
    debugf("mDNSPlatformCloseFD: resetting sources for %d", fd);
    kq->fdClosed = mDNStrue;
#else
    (void)kq; //unused
    close(fd);
#endif
}

mDNSlocal mStatus SetupTCPSocket(TCPSocket *sock, u_short sa_family, mDNSIPPort *port, mDNSBool useBackgroundTrafficClass)
{
    KQSocketSet *cp = &sock->ss;
#ifndef NO_IPV6
    int         *s        = (sa_family == AF_INET) ? &cp->sktv4 : &cp->sktv6;
    KQueueEntry *k        = (sa_family == AF_INET) ? &cp->kqsv4 : &cp->kqsv6;
#else
    int         *s        = &cp->sktv4;
    KQueueEntry *k        = &cp->kqsv4;
#endif
    const int on = 1;  // "on" for setsockopt
    mStatus err;

    int skt = socket(sa_family, SOCK_STREAM, IPPROTO_TCP);
    if (skt < 3) { if (errno != EAFNOSUPPORT) LogMsg("SetupTCPSocket: socket error %d errno %d (%s)", skt, errno, strerror(errno));return(skt); }

    // for TCP sockets, the traffic class is set once and not changed
    setTrafficClass(skt, useBackgroundTrafficClass);

    if (sa_family == AF_INET)
    {
        // Bind it
        struct sockaddr_in addr;
        mDNSPlatformMemZero(&addr, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_port = port->NotAnInteger;
        err = bind(skt, (struct sockaddr*) &addr, sizeof(addr));
        if (err < 0) { LogMsg("ERROR: bind %s", strerror(errno)); return err; }

        // Receive interface identifiers
        err = setsockopt(skt, IPPROTO_IP, IP_RECVIF, &on, sizeof(on));
        if (err < 0) { LogMsg("setsockopt IP_RECVIF - %s", strerror(errno)); return err; }

        mDNSPlatformMemZero(&addr, sizeof(addr));
        socklen_t len = sizeof(addr);
        err = getsockname(skt, (struct sockaddr*) &addr, &len);
        if (err < 0) { LogMsg("getsockname - %s", strerror(errno)); return err; }

        port->NotAnInteger = addr.sin_port;
    }
    else
    {
        // Bind it
        struct sockaddr_in6 addr6;
        mDNSPlatformMemZero(&addr6, sizeof(addr6));
        addr6.sin6_family = AF_INET6;
        addr6.sin6_port = port->NotAnInteger;
        err = bind(skt, (struct sockaddr*) &addr6, sizeof(addr6));
        if (err < 0) { LogMsg("ERROR: bind6 %s", strerror(errno)); return err; }

        // We want to receive destination addresses and receive interface identifiers
        err = setsockopt(skt, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on));
        if (err < 0) { LogMsg("ERROR: setsockopt IPV6_RECVPKTINFO %s", strerror(errno)); return err; }

        mDNSPlatformMemZero(&addr6, sizeof(addr6));
        socklen_t len = sizeof(addr6);
        err = getsockname(skt, (struct sockaddr *) &addr6, &len);
        if (err < 0) { LogMsg("getsockname6 - %s", strerror(errno)); return err; }

        port->NotAnInteger = addr6.sin6_port;

    }
    *s = skt;
    k->KQcallback = tcpKQSocketCallback;
    k->KQcontext  = sock;
    k->KQtask     = "mDNSPlatformTCPSocket";
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
    k->readSource = mDNSNULL;
    k->writeSource = mDNSNULL;
    k->fdClosed = mDNSfalse;
#endif
    return mStatus_NoError;
}

mDNSexport TCPSocket *mDNSPlatformTCPSocket(mDNS *const m, TCPSocketFlags flags, mDNSIPPort *port, mDNSBool useBackgroundTrafficClass)
{
    mStatus err;
    (void) m;

    TCPSocket *sock = mallocL("TCPSocket/mDNSPlatformTCPSocket", sizeof(TCPSocket));
    if (!sock) { LogMsg("mDNSPlatformTCPSocket: memory allocation failure"); return(mDNSNULL); }

    mDNSPlatformMemZero(sock, sizeof(TCPSocket));

    sock->ss.m     = m;
    sock->ss.sktv4 = -1;
#ifndef NO_IPV6
    sock->ss.sktv6 = -1;
#endif
    err = SetupTCPSocket(sock, AF_INET, port, useBackgroundTrafficClass);
#ifndef NO_IPV6
    if (!err)
    {
        err = SetupTCPSocket(sock, AF_INET6, port, useBackgroundTrafficClass);
        if (err) { mDNSPlatformCloseFD(&sock->ss.kqsv4, sock->ss.sktv4); sock->ss.sktv4 = -1; }
    }
#endif
    if (err)
    {
        LogMsg("mDNSPlatformTCPSocket: socket error %d errno %d (%s)", sock->fd, errno, strerror(errno));
        freeL("TCPSocket/mDNSPlatformTCPSocket", sock);
        return(mDNSNULL);
    }
    // sock->fd is used as the default fd  if the caller does not call mDNSPlatformTCPConnect
    sock->fd                = sock->ss.sktv4;
    sock->callback          = mDNSNULL;
    sock->flags             = flags;
    sock->context           = mDNSNULL;
    sock->setup             = mDNSfalse;
    sock->connected         = mDNSfalse;
    sock->handshake         = handshake_required;
    sock->m                 = m;
    sock->err               = mStatus_NoError;

    return sock;
}

mDNSexport mStatus mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr *dst, mDNSOpaque16 dstport, domainname *hostname, mDNSInterfaceID InterfaceID, TCPConnectionCallback callback, void *context)
{
    KQSocketSet *cp = &sock->ss;
#ifndef NO_IPV6
    int         *s        = (dst->type == mDNSAddrType_IPv4) ? &cp->sktv4 : &cp->sktv6;
    KQueueEntry *k        = (dst->type == mDNSAddrType_IPv4) ? &cp->kqsv4 : &cp->kqsv6;
#else
    int         *s        = &cp->sktv4;
    KQueueEntry *k        = &cp->kqsv4;
#endif
    mStatus err = mStatus_NoError;
    struct sockaddr_storage ss;

    sock->callback          = callback;
    sock->context           = context;
    sock->setup             = mDNSfalse;
    sock->connected         = mDNSfalse;
    sock->handshake         = handshake_required;
    sock->err               = mStatus_NoError;

    if (hostname) { debugf("mDNSPlatformTCPConnect: hostname %##s", hostname->c); AssignDomainName(&sock->hostname, hostname); }

    if (dst->type == mDNSAddrType_IPv4)
    {
        struct sockaddr_in *saddr = (struct sockaddr_in *)&ss;
        mDNSPlatformMemZero(saddr, sizeof(*saddr));
        saddr->sin_family      = AF_INET;
        saddr->sin_port        = dstport.NotAnInteger;
        saddr->sin_len         = sizeof(*saddr);
        saddr->sin_addr.s_addr = dst->ip.v4.NotAnInteger;
    }
    else
    {
        struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)&ss;
        mDNSPlatformMemZero(saddr6, sizeof(*saddr6));
        saddr6->sin6_family      = AF_INET6;
        saddr6->sin6_port        = dstport.NotAnInteger;
        saddr6->sin6_len         = sizeof(*saddr6);
        saddr6->sin6_addr        = *(struct in6_addr *)&dst->ip.v6;
    }

    // Watch for connect complete (write is ready)
    // EV_ONESHOT doesn't seem to work, so we add the filter with EV_ADD, and explicitly delete it in tcpKQSocketCallback using EV_DELETE
    if (KQueueSet(*s, EV_ADD /* | EV_ONESHOT */, EVFILT_WRITE, k))
    {
        LogMsg("ERROR: mDNSPlatformTCPConnect - KQueueSet failed");
        return errno;
    }

    // Watch for incoming data
    if (KQueueSet(*s, EV_ADD, EVFILT_READ, k))
    {
        LogMsg("ERROR: mDNSPlatformTCPConnect - KQueueSet failed");
        return errno;
    }

    if (fcntl(*s, F_SETFL, fcntl(*s, F_GETFL, 0) | O_NONBLOCK) < 0) // set non-blocking
    {
        LogMsg("ERROR: setsockopt O_NONBLOCK - %s", strerror(errno));
        return mStatus_UnknownErr;
    }

    // We bind to the interface and all subsequent packets including the SYN will be sent out
    // on this interface
    //
    // Note: If we are in Active Directory domain, we may try TCP (if the response can't fit in
    // UDP). mDNSInterface_Unicast indicates this case and not a valid interface.
    if (InterfaceID && InterfaceID != mDNSInterface_Unicast)
    {
        NetworkInterfaceInfoOSX *info = IfindexToInterfaceInfoOSX(&mDNSStorage, InterfaceID);
        if (dst->type == mDNSAddrType_IPv4)
        {
        #ifdef IP_BOUND_IF
            if (info) setsockopt(*s, IPPROTO_IP, IP_BOUND_IF, &info->scope_id, sizeof(info->scope_id));
            else { LogMsg("mDNSPlatformTCPConnect: Invalid interface index %p", InterfaceID); return mStatus_BadParamErr; }
        #else
            (void)InterfaceID; // Unused
            (void)info; // Unused
        #endif
        }
        else
        {
        #ifdef IPV6_BOUND_IF
            if (info) setsockopt(*s, IPPROTO_IPV6, IPV6_BOUND_IF, &info->scope_id, sizeof(info->scope_id));
            else { LogMsg("mDNSPlatformTCPConnect: Invalid interface index %p", InterfaceID); return mStatus_BadParamErr; }
        #else
            (void)InterfaceID; // Unused
            (void)info; // Unused
        #endif
        }
    }

    // mDNSPlatformReadTCP/WriteTCP (unlike the UDP counterpart) does not provide the destination address
    // from which we can infer the destination address family. Hence we need to remember that here.
    // Instead of remembering the address family, we remember the right fd.
    sock->fd = *s;
    sock->kqEntry = k;
    // initiate connection wth peer
    if (connect(*s, (struct sockaddr *)&ss, ss.ss_len) < 0)
    {
        if (errno == EINPROGRESS) return mStatus_ConnPending;
        if (errno == EHOSTUNREACH || errno == EADDRNOTAVAIL || errno == ENETDOWN)
            LogInfo("ERROR: mDNSPlatformTCPConnect - connect failed: socket %d: Error %d (%s)", sock->fd, errno, strerror(errno));
        else
            LogMsg("ERROR: mDNSPlatformTCPConnect - connect failed: socket %d: Error %d (%s) length %d", sock->fd, errno, strerror(errno), ss.ss_len);
        return mStatus_ConnFailed;
    }

    LogMsg("NOTE: mDNSPlatformTCPConnect completed synchronously");
    // kQueue should notify us, but this LogMsg is to help track down if it doesn't
    return err;
}

// Why doesn't mDNSPlatformTCPAccept actually call accept() ?
mDNSexport TCPSocket *mDNSPlatformTCPAccept(TCPSocketFlags flags, int fd)
{
    mStatus err = mStatus_NoError;

    TCPSocket *sock = mallocL("TCPSocket/mDNSPlatformTCPAccept", sizeof(TCPSocket));
    if (!sock) return(mDNSNULL);

    mDNSPlatformMemZero(sock, sizeof(*sock));
    sock->fd = fd;
    sock->flags = flags;

    if (flags & kTCPSocketFlags_UseTLS)
    {
#ifndef NO_SECURITYFRAMEWORK
        if (!ServerCerts) { LogMsg("ERROR: mDNSPlatformTCPAccept: unable to find TLS certificates"); err = mStatus_UnknownErr; goto exit; }

        err = tlsSetupSock(sock, mDNStrue);
        if (err) { LogMsg("ERROR: mDNSPlatformTCPAccept: tlsSetupSock failed with error code: %d", err); goto exit; }

        err = SSLSetCertificate(sock->tlsContext, ServerCerts);
        if (err) { LogMsg("ERROR: mDNSPlatformTCPAccept: SSLSetCertificate failed with error code: %d", err); goto exit; }
#else
        err = mStatus_UnsupportedErr;
#endif /* NO_SECURITYFRAMEWORK */
    }
#ifndef NO_SECURITYFRAMEWORK
exit:
#endif

    if (err) { freeL("TCPSocket/mDNSPlatformTCPAccept", sock); return(mDNSNULL); }
    return(sock);
}

mDNSlocal void CloseSocketSet(KQSocketSet *ss)
{
    if (ss->sktv4 != -1)
    {
        mDNSPlatformCloseFD(&ss->kqsv4,  ss->sktv4);
        ss->sktv4 = -1;
    }
#ifndef NO_IPV6
    if (ss->sktv6 != -1)
    {
        mDNSPlatformCloseFD(&ss->kqsv6,  ss->sktv6);
        ss->sktv6 = -1;
    }
#endif
    if (ss->closeFlag) *ss->closeFlag = 1;
}

mDNSexport void mDNSPlatformTCPCloseConnection(TCPSocket *sock)
{
    if (sock)
    {
#ifndef NO_SECURITYFRAMEWORK
        if (sock->tlsContext)
        {
            if (sock->handshake == handshake_in_progress) // SSLHandshake thread using this sock (esp. tlsContext)
            {
                LogInfo("mDNSPlatformTCPCloseConnection: called while handshake in progress");
                // When we come back from SSLHandshake, we will notice that a close was here and
                // call this function again which will do the cleanup then.
                sock->handshake = handshake_to_be_closed;
                return;
            }

            SSLClose(sock->tlsContext);
            SSLDisposeContext(sock->tlsContext);
            sock->tlsContext = NULL;
        }
#endif /* NO_SECURITYFRAMEWORK */
        if (sock->ss.sktv4 != -1) shutdown(sock->ss.sktv4, 2);
#ifndef NO_IPV6
        if (sock->ss.sktv6 != -1) shutdown(sock->ss.sktv6, 2);
#endif
        CloseSocketSet(&sock->ss);
        sock->fd = -1;

        freeL("TCPSocket/mDNSPlatformTCPCloseConnection", sock);
    }
}

mDNSexport long mDNSPlatformReadTCP(TCPSocket *sock, void *buf, unsigned long buflen, mDNSBool *closed)
{
    size_t nread = 0;
    *closed = mDNSfalse;

    if (sock->flags & kTCPSocketFlags_UseTLS)
    {
#ifndef NO_SECURITYFRAMEWORK
        if (sock->handshake == handshake_required) { LogMsg("mDNSPlatformReadTCP called while handshake required"); return 0; }
        else if (sock->handshake == handshake_in_progress) return 0;
        else if (sock->handshake != handshake_completed) LogMsg("mDNSPlatformReadTCP called with unexpected SSLHandshake status: %d", sock->handshake);

        //LogMsg("Starting SSLRead %d %X", sock->fd, fcntl(sock->fd, F_GETFL, 0));
        mStatus err = SSLRead(sock->tlsContext, buf, buflen, &nread);
        //LogMsg("SSLRead returned %d (%d) nread %d buflen %d", err, errSSLWouldBlock, nread, buflen);
        if (err == errSSLClosedGraceful) { nread = 0; *closed = mDNStrue; }
        else if (err && err != errSSLWouldBlock)
        { LogMsg("ERROR: mDNSPlatformReadTCP - SSLRead: %d", err); nread = -1; *closed = mDNStrue; }
#else
        nread = -1;
        *closed = mDNStrue;
#endif /* NO_SECURITYFRAMEWORK */
    }
    else
    {
        static int CLOSEDcount = 0;
        static int EAGAINcount = 0;
        nread = recv(sock->fd, buf, buflen, 0);

        if (nread > 0) 
        { 
            CLOSEDcount = 0; 
            EAGAINcount = 0; 
        } // On success, clear our error counters
        else if (nread == 0)
        {
            *closed = mDNStrue;
            if ((++CLOSEDcount % 1000) == 0) 
            { 
                LogMsg("ERROR: mDNSPlatformReadTCP - recv %d got CLOSED %d times", sock->fd, CLOSEDcount); 
                assert(CLOSEDcount < 1000);
                // Recovery Mechanism to bail mDNSResponder out of trouble: Instead of logging the same error msg multiple times,
                // crash mDNSResponder using assert() and restart fresh. See advantages below:
                // 1.Better User Experience 
                // 2.CrashLogs frequency can be monitored 
                // 3.StackTrace can be used for more info
            }
        }
        // else nread is negative -- see what kind of error we got
        else if (errno == ECONNRESET) { nread = 0; *closed = mDNStrue; }
        else if (errno != EAGAIN) { LogMsg("ERROR: mDNSPlatformReadTCP - recv: %d (%s)", errno, strerror(errno)); nread = -1; }
        else // errno is EAGAIN (EWOULDBLOCK) -- no data available
        {
            nread = 0;
            if ((++EAGAINcount % 1000) == 0) { LogMsg("ERROR: mDNSPlatformReadTCP - recv %d got EAGAIN %d times", sock->fd, EAGAINcount); sleep(1); }
        }
    }

    return nread;
}

mDNSexport long mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned long len)
{
    int nsent;

    if (sock->flags & kTCPSocketFlags_UseTLS)
    {
#ifndef NO_SECURITYFRAMEWORK
        size_t processed;
        if (sock->handshake == handshake_required) { LogMsg("mDNSPlatformWriteTCP called while handshake required"); return 0; }
        if (sock->handshake == handshake_in_progress) return 0;
        else if (sock->handshake != handshake_completed) LogMsg("mDNSPlatformWriteTCP called with unexpected SSLHandshake status: %d", sock->handshake);

        mStatus err = SSLWrite(sock->tlsContext, msg, len, &processed);

        if (!err) nsent = (int) processed;
        else if (err == errSSLWouldBlock) nsent = 0;
        else { LogMsg("ERROR: mDNSPlatformWriteTCP - SSLWrite returned %d", err); nsent = -1; }
#else
        nsent = -1;
#endif /* NO_SECURITYFRAMEWORK */
    }
    else
    {
        nsent = send(sock->fd, msg, len, 0);
        if (nsent < 0)
        {
            if (errno == EAGAIN) nsent = 0;
            else { LogMsg("ERROR: mDNSPlatformWriteTCP - send %s", strerror(errno)); nsent = -1; }
        }
    }

    return nsent;
}

mDNSexport int mDNSPlatformTCPGetFD(TCPSocket *sock)
{
    return sock->fd;
}

// If mDNSIPPort port is non-zero, then it's a multicast socket on the specified interface
// If mDNSIPPort port is zero, then it's a randomly assigned port number, used for sending unicast queries
mDNSlocal mStatus SetupSocket(KQSocketSet *cp, const mDNSIPPort port, u_short sa_family, mDNSIPPort *const outport)
{
#ifndef NO_IPV6
    int         *s        = (sa_family == AF_INET) ? &cp->sktv4 : &cp->sktv6;
    KQueueEntry *k        = (sa_family == AF_INET) ? &cp->kqsv4 : &cp->kqsv6;
#else
    int         *s        = &cp->sktv4;
    KQueueEntry *k        = &cp->kqsv4;
#endif
    const int on = 1;
    const int twofivefive = 255;
    mStatus err = mStatus_NoError;
    char *errstr = mDNSNULL;

#ifdef NO_IPV6
    if (sa_family != AF_INET) return -1;
#endif

    cp->closeFlag = mDNSNULL;

    int skt = socket(sa_family, SOCK_DGRAM, IPPROTO_UDP);
    if (skt < 3) { if (errno != EAFNOSUPPORT) LogMsg("SetupSocket: socket error %d errno %d (%s)", skt, errno, strerror(errno));return(skt); }

    // set default traffic class
    setTrafficClass(skt, mDNSfalse);

#ifdef SO_RECV_ANYIF
    // Enable inbound packets on IFEF_AWDL interface.
    // Only done for multicast sockets, since we don't expect unicast socket operations
    // on the IFEF_AWDL interface. Operation is a no-op for other interface types.
    if (mDNSSameIPPort(port, MulticastDNSPort)) 
    {
        err = setsockopt(skt, SOL_SOCKET, SO_RECV_ANYIF, &on, sizeof(on));
        if (err < 0) { errstr = "setsockopt - SO_RECV_ANYIF"; goto fail; }
    }
#endif // SO_RECV_ANYIF

    // ... with a shared UDP port, if it's for multicast receiving
    if (mDNSSameIPPort(port, MulticastDNSPort) || mDNSSameIPPort(port, NATPMPAnnouncementPort)) err = setsockopt(skt, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
    if (err < 0) { errstr = "setsockopt - SO_REUSEPORT"; goto fail; }

    if (sa_family == AF_INET)
    {
        // We want to receive destination addresses
        err = setsockopt(skt, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on));
        if (err < 0) { errstr = "setsockopt - IP_RECVDSTADDR"; goto fail; }

        // We want to receive interface identifiers
        err = setsockopt(skt, IPPROTO_IP, IP_RECVIF, &on, sizeof(on));
        if (err < 0) { errstr = "setsockopt - IP_RECVIF"; goto fail; }

        // 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

        // Send unicast packets with TTL 255
        err = setsockopt(skt, IPPROTO_IP, IP_TTL, &twofivefive, sizeof(twofivefive));
        if (err < 0) { errstr = "setsockopt - IP_TTL"; goto fail; }

        // And multicast packets with TTL 255 too
        err = setsockopt(skt, IPPROTO_IP, IP_MULTICAST_TTL, &twofivefive, sizeof(twofivefive));
        if (err < 0) { errstr = "setsockopt - IP_MULTICAST_TTL"; goto fail; }

        // And start listening for packets
        struct sockaddr_in listening_sockaddr;
        listening_sockaddr.sin_family      = AF_INET;
        listening_sockaddr.sin_port        = port.NotAnInteger;     // Pass in opaque ID without any byte swapping
        listening_sockaddr.sin_addr.s_addr = mDNSSameIPPort(port, NATPMPAnnouncementPort) ? AllHosts_v4.NotAnInteger : 0;
        err = bind(skt, (struct sockaddr *) &listening_sockaddr, sizeof(listening_sockaddr));
        if (err) { errstr = "bind"; goto fail; }
        if (outport) outport->NotAnInteger = listening_sockaddr.sin_port;
    }
#ifndef NO_IPV6
    else if (sa_family == AF_INET6)
    {
        // NAT-PMP Announcements make no sense on IPv6, so bail early w/o error
        if (mDNSSameIPPort(port, NATPMPAnnouncementPort)) { if (outport) *outport = zeroIPPort;return mStatus_NoError; }

        // We want to receive destination addresses and receive interface identifiers
        err = setsockopt(skt, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on));
        if (err < 0) { errstr = "setsockopt - IPV6_RECVPKTINFO"; goto fail; }

        // We want to receive packet hop count value so we can check it
        err = setsockopt(skt, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on));
        if (err < 0) { errstr = "setsockopt - IPV6_RECVHOPLIMIT"; goto fail; }

        // We want to receive only IPv6 packets. Without this option we get IPv4 packets too,
        // with mapped addresses of the form 0:0:0:0:0:FFFF:xxxx:xxxx, where xxxx:xxxx is the IPv4 address
        err = setsockopt(skt, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
        if (err < 0) { errstr = "setsockopt - IPV6_V6ONLY"; goto fail; }

        // Send unicast packets with TTL 255
        err = setsockopt(skt, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &twofivefive, sizeof(twofivefive));
        if (err < 0) { errstr = "setsockopt - IPV6_UNICAST_HOPS"; goto fail; }

        // And multicast packets with TTL 255 too
        err = setsockopt(skt, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &twofivefive, sizeof(twofivefive));
        if (err < 0) { errstr = "setsockopt - IPV6_MULTICAST_HOPS"; goto fail; }

        // Want to receive our own packets
        err = setsockopt(skt, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &on, sizeof(on));
        if (err < 0) { errstr = "setsockopt - IPV6_MULTICAST_LOOP"; goto fail; }

        // And start listening for packets
        struct sockaddr_in6 listening_sockaddr6;
        mDNSPlatformMemZero(&listening_sockaddr6, sizeof(listening_sockaddr6));
        listening_sockaddr6.sin6_len         = sizeof(listening_sockaddr6);
        listening_sockaddr6.sin6_family      = AF_INET6;
        listening_sockaddr6.sin6_port        = port.NotAnInteger;       // Pass in opaque ID without any byte swapping
        listening_sockaddr6.sin6_flowinfo    = 0;
        listening_sockaddr6.sin6_addr        = in6addr_any; // Want to receive multicasts AND unicasts on this socket
        listening_sockaddr6.sin6_scope_id    = 0;
        err = bind(skt, (struct sockaddr *) &listening_sockaddr6, sizeof(listening_sockaddr6));
        if (err) { errstr = "bind"; goto fail; }
        if (outport) outport->NotAnInteger = listening_sockaddr6.sin6_port;
    }
#endif

    fcntl(skt, F_SETFL, fcntl(skt, F_GETFL, 0) | O_NONBLOCK); // set non-blocking
    fcntl(skt, F_SETFD, 1); // set close-on-exec
    *s = skt;
    k->KQcallback = myKQSocketCallBack;
    k->KQcontext  = cp;
    k->KQtask     = "UDP packet reception";
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
    k->readSource = mDNSNULL;
    k->writeSource = mDNSNULL;
    k->fdClosed = mDNSfalse;
#endif
    KQueueSet(*s, EV_ADD, EVFILT_READ, k);

    return(err);

fail:
    // For "bind" failures, only write log messages for our shared mDNS port, or for binding to zero
    if (strcmp(errstr, "bind") || mDNSSameIPPort(port, MulticastDNSPort) || mDNSIPPortIsZero(port))
        LogMsg("%s skt %d port %d error %d errno %d (%s)", errstr, skt, mDNSVal16(port), err, errno, strerror(errno));

    // If we got a "bind" failure of EADDRINUSE, inform the caller as it might need to try another random port
    if (!strcmp(errstr, "bind") && errno == EADDRINUSE)
    {
        err = EADDRINUSE;
        if (mDNSSameIPPort(port, MulticastDNSPort))
            NotifyOfElusiveBug("Setsockopt SO_REUSEPORT failed",
                               "Congratulations, you've reproduced an elusive bug.\r"
                               "Please contact the current assignee of <rdar://problem/3814904>.\r"
                               "Alternatively, you can send email to radar-3387020@group.apple.com. (Note number is different.)\r"
                               "If possible, please leave your machine undisturbed so that someone can come to investigate the problem.");
    }

    mDNSPlatformCloseFD(k, skt);
    return(err);
}

mDNSexport UDPSocket *mDNSPlatformUDPSocket(mDNS *const m, const mDNSIPPort requestedport)
{
    mStatus err;
    mDNSIPPort port = requestedport;
    mDNSBool randomizePort = mDNSIPPortIsZero(requestedport);
    int i = 10000; // Try at most 10000 times to get a unique random port
    UDPSocket *p = mallocL("UDPSocket", sizeof(UDPSocket));
    if (!p) { LogMsg("mDNSPlatformUDPSocket: memory exhausted"); return(mDNSNULL); }
    mDNSPlatformMemZero(p, sizeof(UDPSocket));
    p->ss.port  = zeroIPPort;
    p->ss.m     = m;
    p->ss.sktv4 = -1;
#ifndef NO_IPV6
    p->ss.sktv6 = -1;
#endif

    do
    {
        // The kernel doesn't do cryptographically strong random port allocation, so we do it ourselves here
        if (randomizePort) port = mDNSOpaque16fromIntVal(0xC000 + mDNSRandom(0x3FFF));
        err = SetupSocket(&p->ss, port, AF_INET, &p->ss.port);
#ifndef NO_IPV6
        if (!err)
        {
            err = SetupSocket(&p->ss, port, AF_INET6, &p->ss.port);
            if (err) { mDNSPlatformCloseFD(&p->ss.kqsv4, p->ss.sktv4); p->ss.sktv4 = -1; }
        }
#endif
        i--;
    } while (err == EADDRINUSE && randomizePort && i);

    if (err)
    {
        // In customer builds we don't want to log failures with port 5351, because this is a known issue
        // of failing to bind to this port when Internet Sharing has already bound to it
        // We also don't want to log about port 5350, due to a known bug when some other
        // process is bound to it.
        if (mDNSSameIPPort(requestedport, NATPMPPort) || mDNSSameIPPort(requestedport, NATPMPAnnouncementPort))
            LogInfo("mDNSPlatformUDPSocket: SetupSocket %d failed error %d errno %d (%s)", mDNSVal16(requestedport), err, errno, strerror(errno));
        else LogMsg("mDNSPlatformUDPSocket: SetupSocket %d failed error %d errno %d (%s)", mDNSVal16(requestedport), err, errno, strerror(errno));
        freeL("UDPSocket", p);
        return(mDNSNULL);
    }
    return(p);
}

mDNSexport void mDNSPlatformUDPClose(UDPSocket *sock)
{
    CloseSocketSet(&sock->ss);
    freeL("UDPSocket", sock);
}

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - BPF Raw packet sending/receiving
#endif

#if APPLE_OSX_mDNSResponder

mDNSexport void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
{
    if (!InterfaceID) { LogMsg("mDNSPlatformSendRawPacket: No InterfaceID specified"); return; }
    NetworkInterfaceInfoOSX *info;

    info = IfindexToInterfaceInfoOSX(&mDNSStorage, InterfaceID);
    if (info == NULL)
    {
        LogMsg("mDNSPlatformSendUDP: Invalid interface index %p", InterfaceID);
        return;
    }
    if (info->BPF_fd < 0)
        LogMsg("mDNSPlatformSendRawPacket: %s BPF_fd %d not ready", info->ifinfo.ifname, info->BPF_fd);
    else
    {
        //LogMsg("mDNSPlatformSendRawPacket %d bytes on %s", end - (mDNSu8 *)msg, info->ifinfo.ifname);
        if (write(info->BPF_fd, msg, end - (mDNSu8 *)msg) < 0)
            LogMsg("mDNSPlatformSendRawPacket: BPF write(%d) failed %d (%s)", info->BPF_fd, errno, strerror(errno));
    }
}

mDNSexport void mDNSPlatformSetLocalAddressCacheEntry(mDNS *const m, const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID)
{
    if (!InterfaceID) { LogMsg("mDNSPlatformSetLocalAddressCacheEntry: No InterfaceID specified"); return; }
    NetworkInterfaceInfoOSX *info;
    info = IfindexToInterfaceInfoOSX(m, InterfaceID);
    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))
        LogSPS("Don't need address cache entry for %s %#a %.6a",            info->ifinfo.ifname, tpa, tha);
    else
    {
        int result = mDNSSetLocalAddressCacheEntry(info->scope_id, tpa->type, tpa->ip.v6.b, tha->b);
        if (result) LogMsg("Set local address cache entry for %s %#a %.6a failed: %d", info->ifinfo.ifname, tpa, tha, result);
        else LogSPS("Set local address cache entry for %s %#a %.6a",            info->ifinfo.ifname, tpa, tha);
    }
}

mDNSlocal void CloseBPF(NetworkInterfaceInfoOSX *const i)
{
    LogSPS("%s closing BPF fd %d", i->ifinfo.ifname, i->BPF_fd);
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
    // close will happen in the cancel handler
    dispatch_source_cancel(i->BPF_source);
#else

    // Note: MUST NOT close() the underlying native BSD sockets.
    // CFSocketInvalidate() will do that for us, in its own good time, which may not necessarily be immediately, because
    // it first has to unhook the sockets from its select() call on its other thread, before it can safely close them.
    CFRunLoopRemoveSource(i->m->p->CFRunLoop, i->BPF_rls, kCFRunLoopDefaultMode);
    CFRelease(i->BPF_rls);
    CFSocketInvalidate(i->BPF_cfs);
    CFRelease(i->BPF_cfs);
#endif
    i->BPF_fd = -1;
    if (i->BPF_mcfd >= 0) { close(i->BPF_mcfd); i->BPF_mcfd = -1; }
}

mDNSlocal void bpf_callback_common(NetworkInterfaceInfoOSX *info)
{
    KQueueLock(info->m);

    // Now we've got the lock, make sure the kqueue thread didn't close the fd out from under us (will not be a problem once the OS X
    // kernel has a mechanism for dispatching all events to a single thread, but for now we have to guard against this race condition).
    if (info->BPF_fd < 0) goto exit;

    ssize_t n = read(info->BPF_fd, &info->m->imsg, info->BPF_len);
    const mDNSu8 *ptr = (const mDNSu8 *)&info->m->imsg;
    const mDNSu8 *end = (const mDNSu8 *)&info->m->imsg + n;
    debugf("%3d: bpf_callback got %d bytes on %s", info->BPF_fd, n, info->ifinfo.ifname);

    if (n<0)
    {
        /* <rdar://problem/10287386>
         * sometimes there can be a race condition btw when the bpf socket
         * gets data and the callback get scheduled and when we call BIOCSETF (which
         * clears the socket).  this can cause the read to hang for a really long time
         * and effectively prevent us from responding to requests for long periods of time.
         * to prevent this make the socket non blocking and just bail if we dont get anything
         */
        if (errno == EAGAIN)
        {
            LogMsg("bpf_callback got EAGAIN bailing");
            goto exit;
        }
        LogMsg("Closing %s BPF fd %d due to error %d (%s)", info->ifinfo.ifname, info->BPF_fd, errno, strerror(errno));
        CloseBPF(info);
        goto exit;
    }

    while (ptr < end)
    {
        const struct bpf_hdr *const bh = (const struct bpf_hdr *)ptr;
        debugf("%3d: bpf_callback ptr %p bh_hdrlen %d data %p bh_caplen %4d bh_datalen %4d next %p remaining %4d",
               info->BPF_fd, ptr, bh->bh_hdrlen, ptr + bh->bh_hdrlen, bh->bh_caplen, bh->bh_datalen,
               ptr + BPF_WORDALIGN(bh->bh_hdrlen + bh->bh_caplen), end - (ptr + BPF_WORDALIGN(bh->bh_hdrlen + bh->bh_caplen)));
        // Note that BPF guarantees that the NETWORK LAYER header will be word aligned, not the link-layer header.
        // Given that An Ethernet header is 14 bytes, this means that if the network layer header (e.g. IP header,
        // ARP message, etc.) is 4-byte aligned, then necessarily the Ethernet header will be NOT be 4-byte aligned.
        mDNSCoreReceiveRawPacket(info->m, ptr + bh->bh_hdrlen, ptr + bh->bh_hdrlen + bh->bh_caplen, info->ifinfo.InterfaceID);
        ptr += BPF_WORDALIGN(bh->bh_hdrlen + bh->bh_caplen);
    }
exit:
    KQueueUnlock(info->m, "bpf_callback");
}
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
mDNSlocal void bpf_callback_dispatch(NetworkInterfaceInfoOSX *const info)
{
    bpf_callback_common(info);
}
#else
mDNSlocal void bpf_callback(const CFSocketRef cfs, const CFSocketCallBackType CallBackType, const CFDataRef address, const void *const data, void *const context)
{
    (void)cfs;
    (void)CallBackType;
    (void)address;
    (void)data;
    bpf_callback_common((NetworkInterfaceInfoOSX *)context);
}
#endif

mDNSexport void mDNSPlatformSendKeepalive(mDNSAddr *sadd, mDNSAddr *dadd, mDNSIPPort *lport, mDNSIPPort *rport, mDNSu32 seq, mDNSu32 ack, mDNSu16 win)
{
    LogMsg("mDNSPlatformSendKeepalive called\n");
    mDNSSendKeepalive(sadd->ip.v6.b, dadd->ip.v6.b, lport->NotAnInteger, rport->NotAnInteger, seq, ack, win);
}

#define BPF_SetOffset(from, cond, to) (from)->cond = (to) - 1 - (from)

mDNSlocal int CountProxyTargets(mDNS *const m, NetworkInterfaceInfoOSX *x, int *p4, int *p6)
{
    int numv4 = 0, numv6 = 0;
    AuthRecord *rr;

    for (rr = m->ResourceRecords; rr; rr=rr->next)
        if (rr->resrec.InterfaceID == x->ifinfo.InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv4)
        {
            if (p4) LogSPS("CountProxyTargets: fd %d %-7s IP%2d %.4a", x->BPF_fd, x->ifinfo.ifname, numv4, &rr->AddressProxy.ip.v4);
            numv4++;
        }

    for (rr = m->ResourceRecords; rr; rr=rr->next)
        if (rr->resrec.InterfaceID == x->ifinfo.InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv6)
        {
            if (p6) LogSPS("CountProxyTargets: fd %d %-7s IP%2d %.16a", x->BPF_fd, x->ifinfo.ifname, numv6, &rr->AddressProxy.ip.v6);
            numv6++;
        }

    if (p4) *p4 = numv4;
    if (p6) *p6 = numv6;
    return(numv4 + numv6);
}

mDNSexport void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID)
{
    NetworkInterfaceInfoOSX *x;

    // Note: We can't use IfIndexToInterfaceInfoOSX because that looks for Registered also.
    for (x = m->p->InterfaceList; x; x = x->next) if (x->ifinfo.InterfaceID == InterfaceID) break;

    if (!x) { LogMsg("mDNSPlatformUpdateProxyList: ERROR InterfaceID %p not found", InterfaceID); return; }

    #define MAX_BPF_ADDRS 250
    int numv4 = 0, numv6 = 0;

    if (CountProxyTargets(m, x, &numv4, &numv6) > MAX_BPF_ADDRS)
    {
        LogMsg("mDNSPlatformUpdateProxyList: ERROR Too many address proxy records v4 %d v6 %d", numv4, numv6);
        if (numv4 > MAX_BPF_ADDRS) numv4 = MAX_BPF_ADDRS;
        numv6 = MAX_BPF_ADDRS - numv4;
    }

    LogSPS("mDNSPlatformUpdateProxyList: fd %d %-7s MAC  %.6a %d v4 %d v6", x->BPF_fd, x->ifinfo.ifname, &x->ifinfo.MAC, numv4, numv6);

    // Caution: This is a static structure, so we need to be careful that any modifications we make to it
    // are done in such a way that they work correctly when mDNSPlatformUpdateProxyList is called multiple times
    static struct bpf_insn filter[17 + MAX_BPF_ADDRS] =
    {
        BPF_STMT(BPF_LD  + BPF_H   + BPF_ABS, 12),              // 0 Read Ethertype (bytes 12,13)

        BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0806, 0, 1),      // 1 If Ethertype == ARP goto next, else 3
        BPF_STMT(BPF_RET + BPF_K,             42),              // 2 Return 42-byte ARP

        BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0800, 4, 0),      // 3 If Ethertype == IPv4 goto 8 (IPv4 address list check) else next

        BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x86DD, 0, 9),      // 4 If Ethertype == IPv6 goto next, else exit
        BPF_STMT(BPF_LD  + BPF_H   + BPF_ABS, 20),              // 5 Read Protocol and Hop Limit (bytes 20,21)
        BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x3AFF, 0, 9),      // 6 If (Prot,TTL) == (3A,FF) goto next, else IPv6 address list check
        BPF_STMT(BPF_RET + BPF_K,             86),              // 7 Return 86-byte ND

        // Is IPv4 packet; check if it's addressed to any IPv4 address we're proxying for
        BPF_STMT(BPF_LD  + BPF_W   + BPF_ABS, 30),              // 8 Read IPv4 Dst (bytes 30,31,32,33)
    };

    struct bpf_insn *pc   = &filter[9];
    struct bpf_insn *chk6 = pc   + numv4 + 1;   // numv4 address checks, plus a "return 0"
    struct bpf_insn *fail = chk6 + 1 + numv6;   // Get v6 Dst LSW, plus numv6 address checks
    struct bpf_insn *ret4 = fail + 1;
    struct bpf_insn *ret6 = ret4 + 4;

    static const struct bpf_insn rf  = BPF_STMT(BPF_RET + BPF_K, 0);                // No match: Return nothing

    static const struct bpf_insn g6  = BPF_STMT(BPF_LD  + BPF_W   + BPF_ABS, 50);   // Read IPv6 Dst LSW (bytes 50,51,52,53)

    static const struct bpf_insn r4a = BPF_STMT(BPF_LDX + BPF_B   + BPF_MSH, 14);   // Get IP Header length (normally 20)
    static const struct bpf_insn r4b = BPF_STMT(BPF_LD  + BPF_IMM,           54);   // A = 54 (14-byte Ethernet plus 20-byte TCP + 20 bytes spare)
    static const struct bpf_insn r4c = BPF_STMT(BPF_ALU + BPF_ADD + BPF_X,    0);   // A += IP Header length
    static const struct bpf_insn r4d = BPF_STMT(BPF_RET + BPF_A, 0);                // Success: Return Ethernet + IP + TCP + 20 bytes spare (normally 74)

    static const struct bpf_insn r6a = BPF_STMT(BPF_RET + BPF_K, 94);               // Success: Return Eth + IPv6 + TCP + 20 bytes spare

    BPF_SetOffset(&filter[4], jf, fail);    // If Ethertype not ARP, IPv4, or IPv6, fail
    BPF_SetOffset(&filter[6], jf, chk6);    // If IPv6 but not ICMPv6, go to IPv6 address list check

    // BPF Byte-Order Note
    // The BPF API designers apparently thought that programmers would not be smart enough to use htons
    // and htonl correctly to convert numeric values to network byte order on little-endian machines,
    // so instead they chose to make the API implicitly byte-swap *ALL* values, even literal byte strings
    // that shouldn't be byte-swapped, like ASCII text, Ethernet addresses, IP addresses, etc.
    // As a result, if we put Ethernet addresses and IP addresses in the right byte order, the BPF API
    // will byte-swap and make them backwards, and then our filter won't work. So, we have to arrange
    // that on little-endian machines we deliberately put addresses in memory with the bytes backwards,
    // so that when the BPF API goes through and swaps them all, they end up back as they should be.
    // In summary, if we byte-swap all the non-numeric fields that shouldn't be swapped, and we *don't*
    // swap any of the numeric values that *should* be byte-swapped, then the filter will work correctly.

    // IPSEC capture size notes:
    //  8 bytes UDP header
    //  4 bytes Non-ESP Marker
    // 28 bytes IKE Header
    // --
    // 40 Total. Capturing TCP Header + 20 gets us enough bytes to receive the IKE Header in a UDP-encapsulated IKE packet.

    AuthRecord *rr;
    for (rr = m->ResourceRecords; rr; rr=rr->next)
        if (rr->resrec.InterfaceID == InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv4)
        {
            mDNSv4Addr a = rr->AddressProxy.ip.v4;
            pc->code = BPF_JMP + BPF_JEQ + BPF_K;
            BPF_SetOffset(pc, jt, ret4);
            pc->jf   = 0;
            pc->k    = (bpf_u_int32)a.b[0] << 24 | (bpf_u_int32)a.b[1] << 16 | (bpf_u_int32)a.b[2] << 8 | (bpf_u_int32)a.b[3];
            pc++;
        }
    *pc++ = rf;

    if (pc != chk6) LogMsg("mDNSPlatformUpdateProxyList: pc %p != chk6 %p", pc, chk6);
    *pc++ = g6; // chk6 points here

    // First cancel any previous ND group memberships we had, then create a fresh socket
    if (x->BPF_mcfd >= 0) close(x->BPF_mcfd);
    x->BPF_mcfd = socket(AF_INET6, SOCK_DGRAM, 0);

    for (rr = m->ResourceRecords; rr; rr=rr->next)
        if (rr->resrec.InterfaceID == InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv6)
        {
            const mDNSv6Addr *const a = &rr->AddressProxy.ip.v6;
            pc->code = BPF_JMP + BPF_JEQ + BPF_K;
            BPF_SetOffset(pc, jt, ret6);
            pc->jf   = 0;
            pc->k    = (bpf_u_int32)a->b[0x0C] << 24 | (bpf_u_int32)a->b[0x0D] << 16 | (bpf_u_int32)a->b[0x0E] << 8 | (bpf_u_int32)a->b[0x0F];
            pc++;

            struct ipv6_mreq i6mr;
            i6mr.ipv6mr_interface = x->scope_id;
            i6mr.ipv6mr_multiaddr = *(const struct in6_addr*)&NDP_prefix;
            i6mr.ipv6mr_multiaddr.s6_addr[0xD] = a->b[0xD];
            i6mr.ipv6mr_multiaddr.s6_addr[0xE] = a->b[0xE];
            i6mr.ipv6mr_multiaddr.s6_addr[0xF] = a->b[0xF];

            // Do precautionary IPV6_LEAVE_GROUP first, necessary to clear stale kernel state
            mStatus err = setsockopt(x->BPF_mcfd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &i6mr, sizeof(i6mr));
            if (err < 0 && (errno != EADDRNOTAVAIL))
                LogMsg("mDNSPlatformUpdateProxyList: IPV6_LEAVE_GROUP error %d errno %d (%s) group %.16a on %u", err, errno, strerror(errno), &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);

            err = setsockopt(x->BPF_mcfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &i6mr, sizeof(i6mr));
            if (err < 0 && (errno != EADDRINUSE))   // Joining same group twice can give "Address already in use" error -- no need to report that
                LogMsg("mDNSPlatformUpdateProxyList: IPV6_JOIN_GROUP error %d errno %d (%s) group %.16a on %u", err, errno, strerror(errno), &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);

            LogSPS("Joined IPv6 ND multicast group %.16a for %.16a", &i6mr.ipv6mr_multiaddr, a);
        }

    if (pc != fail) LogMsg("mDNSPlatformUpdateProxyList: pc %p != fail %p", pc, fail);
    *pc++ = rf;     // fail points here

    if (pc != ret4) LogMsg("mDNSPlatformUpdateProxyList: pc %p != ret4 %p", pc, ret4);
    *pc++ = r4a;    // ret4 points here
    *pc++ = r4b;
    *pc++ = r4c;
    *pc++ = r4d;

    if (pc != ret6) LogMsg("mDNSPlatformUpdateProxyList: pc %p != ret6 %p", pc, ret6);
    *pc++ = r6a;    // ret6 points here

    struct bpf_program prog = { pc - filter, filter };

#if 0
    // For debugging BPF filter program
    unsigned int q;
    for (q=0; q<prog.bf_len; q++)
        LogSPS("mDNSPlatformUpdateProxyList: %2d { 0x%02x, %d, %d, 0x%08x },", q, prog.bf_insns[q].code, prog.bf_insns[q].jt, prog.bf_insns[q].jf, prog.bf_insns[q].k);
#endif

    if (!numv4 && !numv6)
    {
        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);
        // 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
    }

    if (ioctl(x->BPF_fd, BIOCSETF, &prog) < 0) LogMsg("mDNSPlatformUpdateProxyList: BIOCSETF(%d) failed %d (%s)", prog.bf_len, errno, strerror(errno));
    else LogSPS("mDNSPlatformUpdateProxyList: BIOCSETF(%d) successful", prog.bf_len);
}

mDNSexport void mDNSPlatformReceiveBPF_fd(mDNS *const m, int fd)
{
    mDNS_Lock(m);

    NetworkInterfaceInfoOSX *i;
    for (i = m->p->InterfaceList; i; i = i->next) if (i->BPF_fd == -2) break;
    if (!i) { LogSPS("mDNSPlatformReceiveBPF_fd: No Interfaces awaiting BPF fd %d; closing", fd); close(fd); }
    else
    {
        LogSPS("%s using   BPF fd %d", i->ifinfo.ifname, fd);

        struct bpf_version v;
        if (ioctl(fd, BIOCVERSION, &v) < 0)
            LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCVERSION failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno));
        else if (BPF_MAJOR_VERSION != v.bv_major || BPF_MINOR_VERSION != v.bv_minor)
            LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCVERSION header %d.%d kernel %d.%d",
                   fd, i->ifinfo.ifname, BPF_MAJOR_VERSION, BPF_MINOR_VERSION, v.bv_major, v.bv_minor);

        if (ioctl(fd, BIOCGBLEN, &i->BPF_len) < 0)
            LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCGBLEN failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno));

        if (i->BPF_len > sizeof(m->imsg))
        {
            i->BPF_len = sizeof(m->imsg);
            if (ioctl(fd, BIOCSBLEN, &i->BPF_len) < 0)
                LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCSBLEN failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno));
            else
                LogSPS("mDNSPlatformReceiveBPF_fd: %d %s BIOCSBLEN %d", fd, i->ifinfo.ifname, i->BPF_len);
        }

        static const u_int opt_one = 1;
        if (ioctl(fd, BIOCIMMEDIATE, &opt_one) < 0)
            LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCIMMEDIATE failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno));

        //if (ioctl(fd, BIOCPROMISC, &opt_one) < 0)
        //	LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCPROMISC failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno));

        //if (ioctl(fd, BIOCSHDRCMPLT, &opt_one) < 0)
        //	LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCSHDRCMPLT failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno));

        /*  <rdar://problem/10287386>
         *  make socket non blocking see comments in bpf_callback_common for more info
         */
        if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK) < 0) // set non-blocking
        {
            LogMsg("mDNSPlatformReceiveBPF_fd: %d %s O_NONBLOCK failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno));
        }

        struct ifreq ifr;
        mDNSPlatformMemZero(&ifr, sizeof(ifr));
        strlcpy(ifr.ifr_name, i->ifinfo.ifname, sizeof(ifr.ifr_name));
        if (ioctl(fd, BIOCSETIF, &ifr) < 0)
        { LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCSETIF failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno)); i->BPF_fd = -3; }
        else
        {
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
            i->BPF_fd  = fd;
            i->BPF_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, fd, 0, dispatch_get_main_queue());
            if (!i->BPF_source) {LogMsg("mDNSPlatformReceiveBPF_fd: dispatch source create failed"); return;}
            dispatch_source_set_event_handler(i->BPF_source, ^{bpf_callback_dispatch(i);});
            dispatch_source_set_cancel_handler(i->BPF_source, ^{close(fd);});
            dispatch_resume(i->BPF_source);
#else
            CFSocketContext myCFSocketContext = { 0, i, NULL, NULL, NULL };
            i->BPF_fd  = fd;
            i->BPF_cfs = CFSocketCreateWithNative(kCFAllocatorDefault, fd, kCFSocketReadCallBack, bpf_callback, &myCFSocketContext);
            i->BPF_rls = CFSocketCreateRunLoopSource(kCFAllocatorDefault, i->BPF_cfs, 0);
            CFRunLoopAddSource(i->m->p->CFRunLoop, i->BPF_rls, kCFRunLoopDefaultMode);
#endif
            mDNSPlatformUpdateProxyList(m, i->ifinfo.InterfaceID);
        }
    }

    mDNS_Unlock(m);
}

#endif // APPLE_OSX_mDNSResponder

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - Key Management
#endif

#ifndef NO_SECURITYFRAMEWORK
mDNSlocal CFArrayRef GetCertChain(SecIdentityRef identity)
{
    CFMutableArrayRef certChain = NULL;
    if (!identity) { LogMsg("getCertChain: identity is NULL"); return(NULL); }
    SecCertificateRef cert;
    OSStatus err = SecIdentityCopyCertificate(identity, &cert);
    if (err || !cert) LogMsg("getCertChain: SecIdentityCopyCertificate() returned %d", (int) err);
    else
    {
        SecPolicySearchRef searchRef;
        err = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &searchRef);
        if (err || !searchRef) LogMsg("getCertChain: SecPolicySearchCreate() returned %d", (int) err);
        else
        {
            SecPolicyRef policy;
            err = SecPolicySearchCopyNext(searchRef, &policy);
            if (err || !policy) LogMsg("getCertChain: SecPolicySearchCopyNext() returned %d", (int) err);
            else
            {
                CFArrayRef wrappedCert = CFArrayCreate(NULL, (const void**) &cert, 1, &kCFTypeArrayCallBacks);
                if (!wrappedCert) LogMsg("getCertChain: wrappedCert is NULL");
                else
                {
                    SecTrustRef trust;
                    err = SecTrustCreateWithCertificates(wrappedCert, policy, &trust);
                    if (err || !trust) LogMsg("getCertChain: SecTrustCreateWithCertificates() returned %d", (int) err);
                    else
                    {
                        err = SecTrustEvaluate(trust, NULL);
                        if (err) LogMsg("getCertChain: 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);
                            else
                            {
                                certChain = CFArrayCreateMutableCopy(NULL, 0, rawCertChain);
                                if (!certChain) LogMsg("getCertChain: certChain is NULL");
                                else
                                {
                                    // Replace the SecCertificateRef at certChain[0] with a SecIdentityRef per documentation for SSLSetCertificate:
                                    // <http://devworld.apple.com/documentation/Security/Reference/secureTransportRef/index.html>
                                    CFArraySetValueAtIndex(certChain, 0, identity);
                                    // Remove root from cert chain, but keep any and all intermediate certificates that have been signed by the root certificate
                                    if (CFArrayGetCount(certChain) > 1) CFArrayRemoveValueAtIndex(certChain, CFArrayGetCount(certChain) - 1);
                                }
                                CFRelease(rawCertChain);
                                // Do not free statusChain:
                                // <http://developer.apple.com/documentation/Security/Reference/certifkeytrustservices/Reference/reference.html> says:
                                // certChain: Call the CFRelease function to release this object when you are finished with it.
                                // statusChain: Do not attempt to free this pointer; it remains valid until the trust management object is released...
                            }
                        }
                        CFRelease(trust);
                    }
                    CFRelease(wrappedCert);
                }
                CFRelease(policy);
            }
            CFRelease(searchRef);
        }
        CFRelease(cert);
    }
    return certChain;
}
#endif /* NO_SECURITYFRAMEWORK */

mDNSexport mStatus mDNSPlatformTLSSetupCerts(void)
{
#ifdef NO_SECURITYFRAMEWORK
    return mStatus_UnsupportedErr;
#else
    SecIdentityRef identity = nil;
    SecIdentitySearchRef srchRef = nil;
    OSStatus err;

    // 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);
    if (err) { LogMsg("ERROR: mDNSPlatformTLSSetupCerts: SecIdentitySearchCreate returned %d", (int) err); return err; }

    err = SecIdentitySearchCopyNext(srchRef, &identity);
    if (err) { LogMsg("ERROR: mDNSPlatformTLSSetupCerts: SecIdentitySearchCopyNext returned %d", (int) err); return err; }

    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; }

    return mStatus_NoError;
#endif /* NO_SECURITYFRAMEWORK */
}

mDNSexport void  mDNSPlatformTLSTearDownCerts(void)
{
#ifndef NO_SECURITYFRAMEWORK
    if (ServerCerts) { CFRelease(ServerCerts); ServerCerts = NULL; }
#endif /* NO_SECURITYFRAMEWORK */
}

// This gets the text of the field currently labelled "Computer Name" in the Sharing Prefs Control Panel
mDNSlocal void GetUserSpecifiedFriendlyComputerName(domainlabel *const namelabel)
{
    CFStringEncoding encoding = kCFStringEncodingUTF8;
    CFStringRef cfs = SCDynamicStoreCopyComputerName(NULL, &encoding);
    if (cfs)
    {
        CFStringGetPascalString(cfs, namelabel->c, sizeof(*namelabel), kCFStringEncodingUTF8);
        CFRelease(cfs);
    }
}

// This gets the text of the field currently labelled "Local Hostname" in the Sharing Prefs Control Panel
mDNSlocal void GetUserSpecifiedLocalHostName(domainlabel *const namelabel)
{
    CFStringRef cfs = SCDynamicStoreCopyLocalHostName(NULL);
    if (cfs)
    {
        CFStringGetPascalString(cfs, namelabel->c, sizeof(*namelabel), kCFStringEncodingUTF8);
        CFRelease(cfs);
    }
}

mDNSexport mDNSBool DictionaryIsEnabled(CFDictionaryRef dict)
{
    mDNSs32 val;
    CFNumberRef state = (CFNumberRef)CFDictionaryGetValue(dict, CFSTR("Enabled"));
    if (!state) return mDNSfalse;
    if (!CFNumberGetValue(state, kCFNumberSInt32Type, &val))
    { LogMsg("ERROR: DictionaryIsEnabled - CFNumberGetValue"); return mDNSfalse; }
    return val ? mDNStrue : mDNSfalse;
}

mDNSlocal mStatus SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa)
{
    if (!sa) { LogMsg("SetupAddr ERROR: NULL sockaddr"); return(mStatus_Invalid); }

    if (sa->sa_family == AF_INET)
    {
        struct sockaddr_in *ifa_addr = (struct sockaddr_in *)sa;
        ip->type = mDNSAddrType_IPv4;
        ip->ip.v4.NotAnInteger = ifa_addr->sin_addr.s_addr;
        return(mStatus_NoError);
    }

    if (sa->sa_family == AF_INET6)
    {
        struct sockaddr_in6 *ifa_addr = (struct sockaddr_in6 *)sa;
        // Inside the BSD kernel they use a hack where they stuff the sin6->sin6_scope_id
        // value into the second word of the IPv6 link-local address, so they can just
        // pass around IPv6 address structures instead of full sockaddr_in6 structures.
        // Those hacked IPv6 addresses aren't supposed to escape the kernel in that form, but they do.
        // To work around this we always whack the second word of any IPv6 link-local address back to zero.
        if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr->sin6_addr)) ifa_addr->sin6_addr.__u6_addr.__u6_addr16[1] = 0;
        ip->type = mDNSAddrType_IPv6;
        ip->ip.v6 = *(mDNSv6Addr*)&ifa_addr->sin6_addr;
        return(mStatus_NoError);
    }

    LogMsg("SetupAddr invalid sa_family %d", sa->sa_family);
    return(mStatus_Invalid);
}

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)
        {
            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);
        }
        CFRelease(store);
    }
    return(eth);
}

mDNSlocal int GetMAC(mDNSEthAddr *eth, u_short ifindex)
{
    struct ifaddrs *ifa;
    for (ifa = myGetIfAddrs(0); ifa; ifa = ifa->ifa_next)
        if (ifa->ifa_addr->sa_family == AF_LINK)
        {
            const struct sockaddr_dl *const sdl = (const struct sockaddr_dl *)ifa->ifa_addr;
            if (sdl->sdl_index == ifindex)
            { mDNSPlatformMemCopy(eth->b, sdl->sdl_data + sdl->sdl_nlen, 6); return 0; }
        }
    *eth = zeroEthAddr;
    return -1;
}

#ifndef SIOCGIFWAKEFLAGS
#define SIOCGIFWAKEFLAGS _IOWR('i', 136, struct ifreq) /* get interface wake property flags */
#endif

#ifndef IF_WAKE_ON_MAGIC_PACKET
#define IF_WAKE_ON_MAGIC_PACKET 0x01
#endif

#ifndef ifr_wake_flags
#define ifr_wake_flags ifr_ifru.ifru_intval
#endif

mDNSlocal mDNSBool NetWakeInterface(NetworkInterfaceInfoOSX *i)
{
    if (!MulticastInterface(i)     ) return(mDNSfalse); // We only use Sleep Proxy Service on multicast-capable interfaces
    if (i->ifa_flags & IFF_LOOPBACK) return(mDNSfalse); // except loopback

    int s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s < 0) { LogMsg("NetWakeInterface socket failed %s error %d errno %d (%s)", i->ifinfo.ifname, s, errno, strerror(errno)); return(mDNSfalse); }

    struct ifreq ifr;
    strlcpy(ifr.ifr_name, i->ifinfo.ifname, sizeof(ifr.ifr_name));
    if (ioctl(s, SIOCGIFWAKEFLAGS, &ifr) < 0)
    {
        // For some strange reason, in /usr/include/sys/errno.h, EOPNOTSUPP is defined to be
        // 102 when compiling kernel code, and 45 when compiling user-level code. Since this
        // error code is being returned from the kernel, we need to use the kernel version.
        #define KERNEL_EOPNOTSUPP 102
        if (errno != KERNEL_EOPNOTSUPP) // "Operation not supported on socket", the expected result on Leopard and earlier
            LogMsg("NetWakeInterface SIOCGIFWAKEFLAGS %s errno %d (%s)", i->ifinfo.ifname, errno, strerror(errno));
        // If on Leopard or earlier, we get EOPNOTSUPP, so in that case
        // we enable WOL if this interface is not AirPort and "Wake for Network access" is turned on.
        ifr.ifr_wake_flags = (errno == KERNEL_EOPNOTSUPP && !(i)->BSSID.l[0] && i->m->SystemWakeOnLANEnabled) ? IF_WAKE_ON_MAGIC_PACKET : 0;
    }

    close(s);

    // ifr.ifr_wake_flags = IF_WAKE_ON_MAGIC_PACKET;	// For testing with MacBook Air, using a USB dongle that doesn't actually support Wake-On-LAN

    LogSPS("%-6s %#-14a %s WOMP", i->ifinfo.ifname, &i->ifinfo.ip, (ifr.ifr_wake_flags & IF_WAKE_ON_MAGIC_PACKET) ? "supports" : "no");

    return((ifr.ifr_wake_flags & IF_WAKE_ON_MAGIC_PACKET) != 0);
}

mDNSlocal u_int64_t getExtendedFlags(char * ifa_name)
{
    int sockFD;
    struct ifreq ifr;

    sockFD = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockFD < 0)
    {
        LogMsg("getExtendedFlags: socket() call failed, errno = %d (%s)", errno, strerror(errno));
        return 0;
    }

    ifr.ifr_addr.sa_family = AF_INET;
    strlcpy(ifr.ifr_name, ifa_name, sizeof(ifr.ifr_name));

    if (ioctl(sockFD, SIOCGIFEFLAGS, (caddr_t)&ifr) == -1)
    {
        LogMsg("getExtendedFlags: SIOCGIFEFLAGS failed, errno = %d (%s)", errno, strerror(errno));
        ifr.ifr_eflags = 0;
    }
    LogInfo("getExtendedFlags: %s ifr_eflags = 0x%x", ifa_name, ifr.ifr_eflags);

    close(sockFD);
    return ifr.ifr_eflags;
}

// 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
// (e.g. sa_family not AF_INET or AF_INET6)
mDNSlocal NetworkInterfaceInfoOSX *AddInterfaceToList(mDNS *const m, struct ifaddrs *ifa, mDNSs32 utc)
{
    mDNSu32 scope_id  = if_nametoindex(ifa->ifa_name);
    mDNSEthAddr bssid = GetBSSID(ifa->ifa_name);
    u_int64_t   eflags = getExtendedFlags(ifa->ifa_name);

    mDNSAddr ip, mask;
    if (SetupAddr(&ip,   ifa->ifa_addr   ) != mStatus_NoError) return(NULL);
    if (SetupAddr(&mask, ifa->ifa_netmask) != mStatus_NoError) return(NULL);

    NetworkInterfaceInfoOSX **p;
    for (p = &m->p->InterfaceList; *p; p = &(*p)->next)
        if (scope_id == (*p)->scope_id &&
            mDNSSameAddress(&ip, &(*p)->ifinfo.ip) &&
            mDNSSameEthAddress(&bssid, &(*p)->BSSID))
        {
            debugf("AddInterfaceToList: Found existing interface %lu %.6a with address %#a at %p, ifname before %s, after %s", scope_id, &bssid, &ip, *p, (*p)->ifinfo.ifname, ifa->ifa_name);
            // The name should be updated to the new name so that we don't report a wrong name in our SIGINFO output.
            // When interfaces are created with same MAC address, kernel resurrects the old interface.
            // Even though the interface index is the same (which should be sufficient), when we receive a UDP packet
            // 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;
            // 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;

            // If Wake-on-LAN capability of this interface has changed (e.g. because power cable on laptop has been disconnected)
            // we may need to start or stop or sleep proxy browse operation
            const mDNSBool NetWake = NetWakeInterface(*p);
            if ((*p)->ifinfo.NetWake != NetWake)
            {
                (*p)->ifinfo.NetWake = NetWake;
                // If this interface is already registered with mDNSCore, then we need to start or stop its NetWake browse on-the-fly.
                // If this interface is not already registered (i.e. it's a dormant interface we had in our list
                // from when we previously saw it) then we mustn't do that, because mDNSCore doesn't know about it yet.
                // In this case, the mDNS_RegisterInterface() call will take care of starting the NetWake browse if necessary.
                if ((*p)->Registered)
                {
                    mDNS_Lock(m);
                    if (NetWake) mDNS_ActivateNetWake_internal  (m, &(*p)->ifinfo);
                    else mDNS_DeactivateNetWake_internal(m, &(*p)->ifinfo);
                    mDNS_Unlock(m);
                }
            }

            return(*p);
        }

    NetworkInterfaceInfoOSX *i = (NetworkInterfaceInfoOSX *)mallocL("NetworkInterfaceInfoOSX", sizeof(*i));
    debugf("AddInterfaceToList: Making   new   interface %lu %.6a with address %#a at %p", scope_id, &bssid, &ip, i);
    if (!i) return(mDNSNULL);
    mDNSPlatformMemZero(i, sizeof(NetworkInterfaceInfoOSX));
    i->ifinfo.InterfaceID = (mDNSInterfaceID)(uintptr_t)scope_id;
    i->ifinfo.ip          = ip;
    i->ifinfo.mask        = mask;
    strlcpy(i->ifinfo.ifname, ifa->ifa_name, sizeof(i->ifinfo.ifname));
    i->ifinfo.ifname[sizeof(i->ifinfo.ifname)-1] = 0;
    // 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->next            = mDNSNULL;
    i->m               = m;
    i->Exists          = mDNStrue;
    i->Flashing        = mDNSfalse;
    i->Occulting       = mDNSfalse;
    i->D2DInterface    = (eflags & IFEF_LOCALNET_PRIVATE) ? mDNStrue: mDNSfalse;
    if (eflags & IFEF_AWDL)
    {
        AWDLInterfaceID = i->ifinfo.InterfaceID;
        LogInfo("AddInterfaceToList: AWDLInterfaceID = %d", (int) AWDLInterfaceID);
    }
    i->AppearanceTime  = utc;       // Brand new interface; AppearanceTime is now
    i->LastSeen        = utc;
    i->ifa_flags       = ifa->ifa_flags;
    i->scope_id        = scope_id;
    i->BSSID           = bssid;
    i->sa_family       = ifa->ifa_addr->sa_family;
    i->BPF_fd          = -1;
    i->BPF_mcfd        = -1;
    i->BPF_len         = 0;
    i->Registered      = mDNSNULL;

    // Do this AFTER i->BSSID has been set up
    i->ifinfo.NetWake  = 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);

    *p = i;
    return(i);
}

#if USE_V6_ONLY_WHEN_NO_ROUTABLE_V4
mDNSlocal NetworkInterfaceInfoOSX *FindRoutableIPv4(mDNS *const m, mDNSu32 scope_id)
{
    NetworkInterfaceInfoOSX *i;
    for (i = m->p->InterfaceList; i; i = i->next)
        if (i->Exists && i->scope_id == scope_id && i->ifinfo.ip.type == mDNSAddrType_IPv4)
            if (!mDNSv4AddressIsLinkLocal(&i->ifinfo.ip.ip.v4))
                return(i);
    return(mDNSNULL);
}
#endif

#if APPLE_OSX_mDNSResponder

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - AutoTunnel
#endif

#define kRacoonPort 4500

static DomainAuthInfo* AnonymousRacoonConfig = mDNSNULL;

#ifndef NO_SECURITYFRAMEWORK

static CFMutableDictionaryRef domainStatusDict = NULL;

mDNSlocal mStatus CheckQuestionForStatus(const DNSQuestion *const q)
{
    if (q->LongLived)
    {
        if (q->servAddr.type == mDNSAddrType_IPv4 && mDNSIPv4AddressIsOnes(q->servAddr.ip.v4))
            return mStatus_NoSuchRecord;
        else if (q->state == LLQ_Poll)
            return mStatus_PollingMode;
        else if (q->state != LLQ_Established && !q->DuplicateOf)
            return mStatus_TransientErr;
    }

    return mStatus_NoError;
}

mDNSlocal mStatus UpdateLLQStatus(const mDNS *const m, char *buffer, int bufsz, const DomainAuthInfo *const info)
{
    mStatus status = mStatus_NoError;
    DNSQuestion* q, *worst_q = mDNSNULL;
    for (q = m->Questions; q; q=q->next)
        if (q->AuthInfo == info)
        {
            mStatus newStatus = CheckQuestionForStatus(q);
            if      (newStatus == mStatus_NoSuchRecord) { status = newStatus; worst_q = q; break; }
            else if (newStatus == mStatus_PollingMode)  { status = newStatus; worst_q = q; }
            else if (newStatus == mStatus_TransientErr && status == mStatus_NoError) { status = newStatus; worst_q = q; }
        }

    if      (status == mStatus_NoError) mDNS_snprintf(buffer, bufsz, "Success");
    else if (status == mStatus_NoSuchRecord) mDNS_snprintf(buffer, bufsz, "GetZoneData %s: %##s", worst_q->nta ? "not yet complete" : "failed", worst_q->qname.c);
    else if (status == mStatus_PollingMode) mDNS_snprintf(buffer, bufsz, "Query polling %##s", worst_q->qname.c);
    else if (status == mStatus_TransientErr) mDNS_snprintf(buffer, bufsz, "Query not yet established %##s", worst_q->qname.c);
    return status;
}

mDNSlocal mStatus UpdateRRStatus(const mDNS *const m, char *buffer, int bufsz, const DomainAuthInfo *const info)
{
    AuthRecord *r;

    if (info->deltime) return mStatus_NoError;
    for (r = m->ResourceRecords; r; r = r->next)
    {
        // This function is called from UpdateAutoTunnelDomainStatus which in turn may be called from
        // a callback e.g., CheckNATMappings. GetAuthInfoFor_internal does not like that (reentrancy being 1),
        // hence we inline the code here. We just need the lock to walk the list of AuthInfos which the caller
        // has already checked
        const domainname *n = r->resrec.name;
        while (n->c[0])
        {
            DomainAuthInfo *ptr;
            for (ptr = m->AuthInfoList; ptr; ptr = ptr->next)
                if (SameDomainName(&ptr->domain, n))
                {
                    if (ptr == info && (r->updateError == mStatus_BadSig || r->updateError == mStatus_BadKey))
                    {
                        mDNS_snprintf(buffer, bufsz, "Resource record update failed for %##s", r->resrec.name);
                        return r->updateError;
                    }
                }
            n = (const domainname *)(n->c + 1 + n->c[0]);
        }
    }
    return mStatus_NoError;
}

#endif // ndef NO_SECURITYFRAMEWORK

// MUST be called with lock held
mDNSlocal void UpdateAutoTunnelDomainStatus(const mDNS *const m, const DomainAuthInfo *const info)
{
#ifdef NO_SECURITYFRAMEWORK
        (void) m;
    (void)info;
#else
    const NATTraversalInfo *const llq = m->LLQNAT.clientContext ? &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;
    CFNumberRef num = NULL;
    mStatus status = mStatus_NoError;
    mStatus llqStatus = mStatus_NoError;
    char llqBuffer[1024];

    mDNS_CheckLock(m);

    if (!domainStatusDict)
    {
        domainStatusDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        if (!domainStatusDict) { LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFDictionary domainStatusDict"); return; }
    }

    if (!dict) { LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFDictionary dict"); return; }

    buflen = mDNS_snprintf(buffer, sizeof(buffer), "%##s", info->domain.c);
    domain = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
    if (!domain) { LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString domain"); return; }

    if (info->deltime)
    {
        if (CFDictionaryContainsKey(domainStatusDict, domain))
        {
            CFDictionaryRemoveValue(domainStatusDict, domain);
            if (!m->ShutdownTime) mDNSDynamicStoreSetConfig(kmDNSBackToMyMacConfig, mDNSNULL, domainStatusDict);
        }
        CFRelease(domain);
        CFRelease(dict);

        return;
    }

    mDNS_snprintf(buffer, sizeof(buffer), "%#a", &m->Router);
    tmp = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
    if (!tmp)
        LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString RouterAddress");
    else
    {
        CFDictionarySetValue(dict, CFSTR("RouterAddress"), tmp);
        CFRelease(tmp);
    }

    mDNS_snprintf(buffer, sizeof(buffer), "%.4a", &m->ExternalAddress);
    tmp = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
    if (!tmp)
        LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString ExternalAddress");
    else
    {
        CFDictionarySetValue(dict, CFSTR("ExternalAddress"), tmp);
        CFRelease(tmp);
    }

    if (llq)
    {
        mDNSu32 port = mDNSVal16(llq->ExternalPort);

        num = CFNumberCreate(NULL, kCFNumberSInt32Type, &port);
        if (!num)
            LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber LLQExternalPort");
        else
        {
            CFDictionarySetValue(dict, CFSTR("LLQExternalPort"), num);
            CFRelease(num);
        }

        if (llq->Result)
        {
            num = CFNumberCreate(NULL, kCFNumberSInt32Type, &llq->Result);
            if (!num)
                LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber LLQNPMStatus");
            else
            {
                CFDictionarySetValue(dict, CFSTR("LLQNPMStatus"), num);
                CFRelease(num);
            }
        }
    }

    if (tun)
    {
        mDNSu32 port = mDNSVal16(tun->ExternalPort);

        num = CFNumberCreate(NULL, kCFNumberSInt32Type, &port);
        if (!num)
            LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber AutoTunnelExternalPort");
        else
        {
            CFDictionarySetValue(dict, CFSTR("AutoTunnelExternalPort"), num);
            CFRelease(num);
        }

        if (tun->Result)
        {
            num = CFNumberCreate(NULL, kCFNumberSInt32Type, &tun->Result);
            if (!num)
                LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber AutoTunnelNPMStatus");
            else
            {
                CFDictionarySetValue(dict, CFSTR("AutoTunnelNPMStatus"), num);
                CFRelease(num);
            }
        }
    }
    if (tun || llq)
    {
        mDNSu32 code = m->LastNATMapResultCode;

        num = CFNumberCreate(NULL, kCFNumberSInt32Type, &code);
        if (!num)
            LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber LastNATMapResultCode");
        else
        {
            CFDictionarySetValue(dict, CFSTR("LastNATMapResultCode"), num);
            CFRelease(num);
        }
    }

    mDNS_snprintf(buffer, sizeof(buffer), "Success");
    llqStatus = UpdateLLQStatus(m, llqBuffer, sizeof(llqBuffer), info);
    status = UpdateRRStatus(m, buffer, sizeof(buffer), info);

    // If we have a bad signature error updating a RR, it overrides any error as it needs to be
    // reported so that it can be fixed automatically (or the user needs to be notified)
    if (status != mStatus_NoError)
    {
        LogInfo("UpdateAutoTunnelDomainStatus: RR Status %d, %s", status, buffer);
    }
    else if (m->Router.type == mDNSAddrType_None)
    {
        status = mStatus_NoRouter;
        mDNS_snprintf(buffer, sizeof(buffer), "No network connection - none");
    }
    else if (m->Router.type == mDNSAddrType_IPv4 && mDNSIPv4AddressIsZero(m->Router.ip.v4))
    {
        status = mStatus_NoRouter;
        mDNS_snprintf(buffer, sizeof(buffer), "No network connection - v4 zero");
    }
    else if (mDNSIPv6AddressIsZero(info->AutoTunnelInnerAddress))
    {
        status = mStatus_ServiceNotRunning;
        mDNS_snprintf(buffer, sizeof(buffer), "No inner address");
    }
    else if (!llq && !tun)
    {
        status = mStatus_NotInitializedErr;
        mDNS_snprintf(buffer, sizeof(buffer), "Neither LLQ nor AutoTunnel NAT port mapping is currently active");
    }
    else if (llqStatus == mStatus_NoSuchRecord)
    {
        status = llqStatus;
        mDNS_snprintf(buffer, sizeof(buffer), llqBuffer);
    }
    else if ((llq && llq->Result == mStatus_DoubleNAT) || (tun && tun->Result == mStatus_DoubleNAT))
    {
        status = mStatus_DoubleNAT;
        mDNS_snprintf(buffer, sizeof(buffer), "Double NAT: Router is reporting an external address");
    }
    else if ((llq && llq->Result == mStatus_NATPortMappingDisabled) ||
             (tun && tun->Result == mStatus_NATPortMappingDisabled) ||
             (m->LastNATMapResultCode == NATErr_Refused && ((llq && !llq->Result && mDNSIPPortIsZero(llq->ExternalPort)) || (tun && !tun->Result && mDNSIPPortIsZero(tun->ExternalPort)))))
    {
        status = mStatus_NATPortMappingDisabled;
        mDNS_snprintf(buffer, sizeof(buffer), "NAT-PMP is disabled on the router");
    }
    else if ((llq && llq->Result) || (tun && tun->Result))
    {
        status = mStatus_NATTraversal;
        mDNS_snprintf(buffer, sizeof(buffer), "Error obtaining NAT port mapping from router");
    }
    else if ((llq && mDNSIPPortIsZero(llq->ExternalPort)) || (tun && mDNSIPPortIsZero(tun->ExternalPort)))
    {
        status = mStatus_NATTraversal;
        mDNS_snprintf(buffer, sizeof(buffer), "Unable to obtain NAT port mapping from router");
    }
    else
    {
        status = llqStatus;
        mDNS_snprintf(buffer, sizeof(buffer), llqBuffer);
        LogInfo("UpdateAutoTunnelDomainStatus: LLQ Status %d, %s", status, buffer);
    }

    num = CFNumberCreate(NULL, kCFNumberSInt32Type, &status);
    if (!num)
        LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber StatusCode");
    else
    {
        CFDictionarySetValue(dict, CFSTR("StatusCode"), num);
        CFRelease(num);
    }

    tmp = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
    if (!tmp)
        LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString StatusMessage");
    else
    {
        CFDictionarySetValue(dict, CFSTR("StatusMessage"), tmp);
        CFRelease(tmp);
    }

    if (!CFDictionaryContainsKey(domainStatusDict, domain) ||
        !CFEqual(dict, (CFMutableDictionaryRef)CFDictionaryGetValue(domainStatusDict, domain)))
    {
        CFDictionarySetValue(domainStatusDict, domain, dict);
        if (!m->ShutdownTime)
        {
            static char statusBuf[16];
            mDNS_snprintf(statusBuf, sizeof(statusBuf), "%d", (int)status);
            mDNSASLLog((uuid_t *)&m->asl_uuid, "autotunnel.domainstatus", status ? "failure" : "success", statusBuf, "");
            mDNSDynamicStoreSetConfig(kmDNSBackToMyMacConfig, mDNSNULL, domainStatusDict);
        }
    }

    CFRelease(domain);
    CFRelease(dict);

    debugf("UpdateAutoTunnelDomainStatus: %s", buffer);
#endif // def NO_SECURITYFRAMEWORK
}

// MUST be called with lock held
mDNSexport void UpdateAutoTunnelDomainStatuses(const mDNS *const m)
{
#ifdef NO_SECURITYFRAMEWORK
        (void) m;
#else
    mDNS_CheckLock(m);
    DomainAuthInfo* info;
    for (info = m->AuthInfoList; info; info = info->next)
        if (info->AutoTunnel && !info->deltime)
            UpdateAutoTunnelDomainStatus(m, info);
#endif // def NO_SECURITYFRAMEWORK
}

mDNSlocal void UpdateAnonymousRacoonConfig(mDNS *m)     // Determine whether we need racoon to accept incoming connections
{
    DomainAuthInfo *info;

    for (info = m->AuthInfoList; info; info = info->next)
        if (info->AutoTunnel && !info->deltime && (!mDNSIPPortIsZero(m->AutoTunnelNAT.ExternalPort) || !mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddr)))
            break;

    if (info != AnonymousRacoonConfig)
    {
        AnonymousRacoonConfig = info;
        // Create or revert configuration file, and start (or SIGHUP) Racoon
        (void)mDNSConfigureServer(AnonymousRacoonConfig ? kmDNSUp : kmDNSDown, AnonymousRacoonConfig ? btmmprefix : mDNSNULL, AnonymousRacoonConfig ? &AnonymousRacoonConfig->domain : mDNSNULL);
    }
}

mDNSlocal void AutoTunnelRecordCallback(mDNS *const m, AuthRecord *const rr, mStatus result);

// Caller must hold the lock
mDNSlocal mDNSBool DeregisterAutoTunnelRecord(mDNS *m, DomainAuthInfo *info, AuthRecord* record)
{
    mDNS_CheckLock(m);

    LogInfo("DeregisterAutoTunnelRecord %##s %##s", &info->domain.c, record->namestorage.c);

    if (record->resrec.RecordType > kDNSRecordTypeDeregistering)
    {
        mStatus err = mDNS_Deregister_internal(m, record, mDNS_Dereg_normal);
        if (err)
        {
            record->resrec.RecordType = kDNSRecordTypeUnregistered;
            LogMsg("DeregisterAutoTunnelRecord error %d deregistering %##s %##s", err, info->domain.c, record->namestorage.c);
            return mDNSfalse;
        }
        else LogInfo("DeregisterAutoTunnelRecord: Deregistered");
    }
    else LogInfo("DeregisterAutoTunnelRecord: Not deregistering, state:%d", record->resrec.RecordType);

    return mDNStrue;
}

// Caller must hold the lock
mDNSlocal void DeregisterAutoTunnelHostRecord(mDNS *m, DomainAuthInfo *info)
{
    if (!DeregisterAutoTunnelRecord(m, info, &info->AutoTunnelHostRecord))
    {
        info->AutoTunnelHostRecord.namestorage.c[0] = 0;
        m->NextSRVUpdate = NonZeroTime(m->timenow);
    }
}

// Caller must hold the lock
mDNSlocal void UpdateAutoTunnelHostRecord(mDNS *m, DomainAuthInfo *info)
{
    mStatus err;
    mDNSBool NATProblem = mDNSIPPortIsZero(m->AutoTunnelNAT.ExternalPort) || m->AutoTunnelNAT.Result;

    mDNS_CheckLock(m);

    if (!info->AutoTunnelServiceStarted || info->deltime || m->ShutdownTime || mDNSIPv6AddressIsZero(info->AutoTunnelInnerAddress) || (m->SleepState != SleepState_Awake && NATProblem))
    {
        LogInfo("UpdateAutoTunnelHostRecord: Dereg %##s : AutoTunnelServiceStarted(%d) deltime(%d) address(%.16a) sleepstate(%d)",
                info->domain.c, info->AutoTunnelServiceStarted, info->deltime, &info->AutoTunnelInnerAddress, m->SleepState);
        DeregisterAutoTunnelHostRecord(m, info);
    }
    else if (info->AutoTunnelHostRecord.resrec.RecordType == kDNSRecordTypeUnregistered)
    {
        mDNS_SetupResourceRecord(&info->AutoTunnelHostRecord, mDNSNULL, mDNSInterface_Any, kDNSType_AAAA, kHostNameTTL,
                                 kDNSRecordTypeUnregistered, AuthRecordAny, AutoTunnelRecordCallback, info);
        info->AutoTunnelHostRecord.namestorage.c[0] = 0;
        AppendDomainLabel(&info->AutoTunnelHostRecord.namestorage, &m->hostlabel);
        AppendDomainName (&info->AutoTunnelHostRecord.namestorage, &info->domain);
        info->AutoTunnelHostRecord.resrec.rdata->u.ipv6 = info->AutoTunnelInnerAddress;
        info->AutoTunnelHostRecord.resrec.RecordType = kDNSRecordTypeKnownUnique;

        err = mDNS_Register_internal(m, &info->AutoTunnelHostRecord);
        if (err) LogMsg("UpdateAutoTunnelHostRecord error %d registering %##s", err, info->AutoTunnelHostRecord.namestorage.c);
        else
        {
            // Make sure we trigger the registration of all SRV records in regState_NoTarget again
            m->NextSRVUpdate = NonZeroTime(m->timenow);
            LogInfo("UpdateAutoTunnelHostRecord registering %##s", info->AutoTunnelHostRecord.namestorage.c);
        }
    }
    else LogInfo("UpdateAutoTunnelHostRecord: Type %d", info->AutoTunnelHostRecord.resrec.RecordType);
}

// Caller must hold the lock
mDNSlocal void DeregisterAutoTunnelServiceRecords(mDNS *m, DomainAuthInfo *info)
{
    LogInfo("DeregisterAutoTunnelServiceRecords %##s", info->domain.c);

    DeregisterAutoTunnelRecord(m, info, &info->AutoTunnelTarget);
    DeregisterAutoTunnelRecord(m, info, &info->AutoTunnelService);
    UpdateAutoTunnelHostRecord(m, info);
}

// Caller must hold the lock
mDNSlocal void UpdateAutoTunnelServiceRecords(mDNS *m, DomainAuthInfo *info)
{
    mDNS_CheckLock(m);

    if (!info->AutoTunnelServiceStarted || info->deltime || m->ShutdownTime || mDNSIPPortIsZero(m->AutoTunnelNAT.ExternalPort) || m->AutoTunnelNAT.Result)
    {
        LogInfo("UpdateAutoTunnelServiceRecords: Dereg %##s : AutoTunnelServiceStarted(%d) deltime(%d) ExtPort(%d) NATResult(%d)", info->domain.c, info->AutoTunnelServiceStarted, info->deltime, mDNSVal16(m->AutoTunnelNAT.ExternalPort), m->AutoTunnelNAT.Result);
        DeregisterAutoTunnelServiceRecords(m, info);
    }
    else
    {
        if (info->AutoTunnelTarget.resrec.RecordType == kDNSRecordTypeUnregistered)
        {
            // 1. Set up our address record for the external tunnel address
            // (Constructed name, not generally user-visible, used as target in IKE tunnel's SRV record)
            mDNS_SetupResourceRecord(&info->AutoTunnelTarget, mDNSNULL, mDNSInterface_Any, kDNSType_A, kHostNameTTL,
                                     kDNSRecordTypeUnregistered, AuthRecordAny, AutoTunnelRecordCallback, info);
            AssignDomainName (&info->AutoTunnelTarget.namestorage, (const domainname*) "\x0B" "_autotunnel");
            AppendDomainLabel(&info->AutoTunnelTarget.namestorage, &m->hostlabel);
            AppendDomainName (&info->AutoTunnelTarget.namestorage, &info->domain);
            info->AutoTunnelTarget.resrec.rdata->u.ipv4 = m->AutoTunnelNAT.ExternalAddress;
            info->AutoTunnelTarget.resrec.RecordType = kDNSRecordTypeKnownUnique;

            mStatus err = mDNS_Register_internal(m, &info->AutoTunnelTarget);
            if (err) LogMsg("UpdateAutoTunnelServiceRecords error %d registering %##s", err, info->AutoTunnelTarget.namestorage.c);
            else LogInfo("UpdateAutoTunnelServiceRecords registering %##s", info->AutoTunnelTarget.namestorage.c);
        }
        else LogInfo("UpdateAutoTunnelServiceRecords: NOOP Target state(%d)", info->AutoTunnelTarget.resrec.RecordType);

        if (info->AutoTunnelService.resrec.RecordType == kDNSRecordTypeUnregistered)
        {
            // 2. Set up IKE tunnel's SRV record: _autotunnel._udp.AutoTunnelHost SRV 0 0 port AutoTunnelTarget
            mDNS_SetupResourceRecord(&info->AutoTunnelService, mDNSNULL, mDNSInterface_Any, kDNSType_SRV,  kHostNameTTL,
                                     kDNSRecordTypeUnregistered, AuthRecordAny, AutoTunnelRecordCallback, info);
            AssignDomainName (&info->AutoTunnelService.namestorage, (const domainname*) "\x0B" "_autotunnel" "\x04" "_udp");
            AppendDomainLabel(&info->AutoTunnelService.namestorage, &m->hostlabel);
            AppendDomainName (&info->AutoTunnelService.namestorage, &info->domain);
            info->AutoTunnelService.resrec.rdata->u.srv.priority = 0;
            info->AutoTunnelService.resrec.rdata->u.srv.weight   = 0;
            info->AutoTunnelService.resrec.rdata->u.srv.port     = m->AutoTunnelNAT.ExternalPort;
            AssignDomainName(&info->AutoTunnelService.resrec.rdata->u.srv.target, &info->AutoTunnelTarget.namestorage);
            info->AutoTunnelService.resrec.RecordType = kDNSRecordTypeKnownUnique;

            mStatus err = mDNS_Register_internal(m, &info->AutoTunnelService);
            if (err) LogMsg("UpdateAutoTunnelServiceRecords error %d registering %##s", err, info->AutoTunnelService.namestorage.c);
            else LogInfo("UpdateAutoTunnelServiceRecords registering %##s", info->AutoTunnelService.namestorage.c);
        }
        else LogInfo("UpdateAutoTunnelServiceRecords: NOOP Service state(%d)", info->AutoTunnelService.resrec.RecordType);

        UpdateAutoTunnelHostRecord(m, info);

        LogInfo("AutoTunnel server listening for connections on %##s[%.4a]:%d:%##s[%.16a]",
                info->AutoTunnelTarget.namestorage.c,     &m->AdvertisedV4.ip.v4, mDNSVal16(m->AutoTunnelNAT.IntPort),
                info->AutoTunnelHostRecord.namestorage.c, &info->AutoTunnelInnerAddress);

    }
}

// Caller must hold the lock
mDNSlocal void DeregisterAutoTunnelDeviceInfoRecord(mDNS *m, DomainAuthInfo *info)
{
    DeregisterAutoTunnelRecord(m, info, &info->AutoTunnelDeviceInfo);
}

// Caller must hold the lock
mDNSlocal void UpdateAutoTunnelDeviceInfoRecord(mDNS *m, DomainAuthInfo *info)
{
    mDNS_CheckLock(m);

    if (!info->AutoTunnelServiceStarted || info->deltime || m->ShutdownTime)
        DeregisterAutoTunnelDeviceInfoRecord(m, info);
    else if (info->AutoTunnelDeviceInfo.resrec.RecordType == kDNSRecordTypeUnregistered)
    {
        mDNS_SetupResourceRecord(&info->AutoTunnelDeviceInfo, mDNSNULL, mDNSInterface_Any, kDNSType_TXT,  kStandardTTL, kDNSRecordTypeUnregistered, AuthRecordAny, AutoTunnelRecordCallback, info);
        ConstructServiceName(&info->AutoTunnelDeviceInfo.namestorage, &m->nicelabel, &DeviceInfoName, &info->domain);
        mDNSu8 len = m->HIHardware.c[0] < 255 - 6 ? m->HIHardware.c[0] : 255 - 6;
        mDNSPlatformMemCopy(info->AutoTunnelDeviceInfo.resrec.rdata->u.data + 1, "model=", 6);
        mDNSPlatformMemCopy(info->AutoTunnelDeviceInfo.resrec.rdata->u.data + 7, m->HIHardware.c + 1, len);
        info->AutoTunnelDeviceInfo.resrec.rdata->u.data[0] = 6 + len;   // "model=" plus the device string
        info->AutoTunnelDeviceInfo.resrec.rdlength         = 7 + len;   // One extra for the length byte at the start of the string
        info->AutoTunnelDeviceInfo.resrec.RecordType = kDNSRecordTypeKnownUnique;

        mStatus err = mDNS_Register_internal(m, &info->AutoTunnelDeviceInfo);
        if (err) LogMsg("UpdateAutoTunnelDeviceInfoRecord error %d registering %##s", err, info->AutoTunnelDeviceInfo.namestorage.c);
        else LogInfo("UpdateAutoTunnelDeviceInfoRecord registering %##s", info->AutoTunnelDeviceInfo.namestorage.c);
    }
    else
        LogInfo("UpdateAutoTunnelDeviceInfoRecord: not in Unregistered state: %d",info->AutoTunnelDeviceInfo.resrec.RecordType);
}

// Caller must hold the lock
mDNSlocal void DeregisterAutoTunnel6Record(mDNS *m, DomainAuthInfo *info)
{
    LogInfo("DeregisterAutoTunnel6Record %##s", info->domain.c);

    DeregisterAutoTunnelRecord(m, info, &info->AutoTunnel6Record);
    UpdateAutoTunnelHostRecord(m, info);
    UpdateAutoTunnelDomainStatus(m, info);
}

// Caller must hold the lock
mDNSlocal void UpdateAutoTunnel6Record(mDNS *m, DomainAuthInfo *info)
{
    mDNS_CheckLock(m);

    if (!info->AutoTunnelServiceStarted || info->deltime || m->ShutdownTime || mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddr) || m->SleepState != SleepState_Awake)
        DeregisterAutoTunnel6Record(m, info);
    else if (info->AutoTunnel6Record.resrec.RecordType == kDNSRecordTypeUnregistered)
    {
        mDNS_SetupResourceRecord(&info->AutoTunnel6Record, mDNSNULL, mDNSInterface_Any, kDNSType_AAAA, kHostNameTTL,
                                 kDNSRecordTypeUnregistered, AuthRecordAny, AutoTunnelRecordCallback, info);
        AssignDomainName (&info->AutoTunnel6Record.namestorage, (const domainname*) "\x0C" "_autotunnel6");
        AppendDomainLabel(&info->AutoTunnel6Record.namestorage, &m->hostlabel);
        AppendDomainName (&info->AutoTunnel6Record.namestorage, &info->domain);
        info->AutoTunnel6Record.resrec.rdata->u.ipv6 = m->AutoTunnelRelayAddr;
        info->AutoTunnel6Record.resrec.RecordType = kDNSRecordTypeKnownUnique;

        mStatus err = mDNS_Register_internal(m, &info->AutoTunnel6Record);
        if (err) LogMsg("UpdateAutoTunnel6Record error %d registering %##s", err, info->AutoTunnel6Record.namestorage.c);
        else LogInfo("UpdateAutoTunnel6Record registering %##s", info->AutoTunnel6Record.namestorage.c);

        UpdateAutoTunnelHostRecord(m, info);

        LogInfo("AutoTunnel6 server listening for connections on %##s[%.16a] :%##s[%.16a]",
                info->AutoTunnel6Record.namestorage.c,    &m->AutoTunnelRelayAddr,
                info->AutoTunnelHostRecord.namestorage.c, &info->AutoTunnelInnerAddress);

    }
    else LogInfo("UpdateAutoTunnel6Record NOOP state(%d)",info->AutoTunnel6Record.resrec.RecordType);
}

mDNSlocal void AutoTunnelRecordCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
{
    DomainAuthInfo *info = (DomainAuthInfo *)rr->RecordContext;
    if (result == mStatus_MemFree)
    {
        LogInfo("AutoTunnelRecordCallback MemFree %s", ARDisplayString(m, rr));
        
        mDNS_Lock(m);
        
        // Reset the host record namestorage to force high-level PTR/SRV/TXT to deregister
        if (rr == &info->AutoTunnelHostRecord)
        {
            rr->namestorage.c[0] = 0;
            m->NextSRVUpdate = NonZeroTime(m->timenow);
            LogInfo("AutoTunnelRecordCallback: NextSRVUpdate in %d %d", m->NextSRVUpdate - m->timenow, m->timenow);
        }
        if (m->ShutdownTime)
        {
            LogInfo("AutoTunnelRecordCallback: Shutdown, returning");
            mDNS_Unlock(m);        
            return;
        }
        if (rr == &info->AutoTunnelHostRecord)
        {
            LogInfo("AutoTunnelRecordCallback: calling UpdateAutoTunnelHostRecord");
            UpdateAutoTunnelHostRecord(m,info);
        }
        else if (rr == &info->AutoTunnelDeviceInfo)
        {
            LogInfo("AutoTunnelRecordCallback: Calling UpdateAutoTunnelDeviceInfoRecord");
            UpdateAutoTunnelDeviceInfoRecord(m,info);
        }
        else if (rr == &info->AutoTunnelService || rr == &info->AutoTunnelTarget)
        {
            LogInfo("AutoTunnelRecordCallback: Calling UpdateAutoTunnelServiceRecords");
            UpdateAutoTunnelServiceRecords(m,info);
        }
        else if (rr == &info->AutoTunnel6Record)
        {
            LogInfo("AutoTunnelRecordCallback: Calling UpdateAutoTunnel6Record");
            UpdateAutoTunnel6Record(m,info);
        }

        mDNS_Unlock(m);        
    }
}

mDNSlocal void AutoTunnelNATCallback(mDNS *m, NATTraversalInfo *n)
{
    DomainAuthInfo *info;

    LogInfo("AutoTunnelNATCallback Result %d %.4a Internal %d External %d",
            n->Result, &n->ExternalAddress, mDNSVal16(n->IntPort), mDNSVal16(n->ExternalPort));

    mDNS_Lock(m);
    
    m->NextSRVUpdate = NonZeroTime(m->timenow);
    LogInfo("AutoTunnelNATCallback: NextSRVUpdate in %d %d", m->NextSRVUpdate - m->timenow, m->timenow);

    for (info = m->AuthInfoList; info; info = info->next)
        if (info->AutoTunnel)
            UpdateAutoTunnelServiceRecords(m, info);

    UpdateAnonymousRacoonConfig(m);     // Determine whether we need racoon to accept incoming connections

    UpdateAutoTunnelDomainStatuses(m);

    mDNS_Unlock(m);
}

mDNSlocal void AutoTunnelHostNameChanged(mDNS *m, DomainAuthInfo *info)
{
    LogInfo("AutoTunnelHostNameChanged %#s.%##s", m->hostlabel.c, info->domain.c);

    mDNS_Lock(m);
    // We forcibly deregister the records that are based on the hostname.
    // When deregistration of each completes, the MemFree callback will make the
    // appropriate Update* call to use the new name to reregister.
    DeregisterAutoTunnelHostRecord(m, info);
    DeregisterAutoTunnelDeviceInfoRecord(m, info);
    DeregisterAutoTunnelServiceRecords(m, info);
    DeregisterAutoTunnel6Record(m, info);
    m->NextSRVUpdate = NonZeroTime(m->timenow);
    mDNS_Unlock(m);
}

// Must be called with the lock held
mDNSexport void StartServerTunnel(mDNS *const m, DomainAuthInfo *const info)
{
    if (info->deltime) return;
    
    if (info->AutoTunnelServiceStarted)
    {
        // On wake from sleep, this function will be called when determining SRV targets,
        // and needs to re-register the host record for the target to be set correctly
        UpdateAutoTunnelHostRecord(m, info);
        return;
    }
    
    info->AutoTunnelServiceStarted = mDNStrue;

    // Now that we have a service in this domain, we need to try to register the
    // AutoTunnel records, because the relay connection & NAT-T may have already been
    // started for another domain. If the relay connection is not up or the NAT-T has not
    // yet succeeded, the Update* functions are smart enough to not register the records.
    // Note: This should be done after we set AutoTunnelServiceStarted, as that variable is used to
    // decide whether to register the AutoTunnel records in the calls below.
    UpdateAutoTunnelServiceRecords(m, info);
    UpdateAutoTunnel6Record(m, info);
    UpdateAutoTunnelDeviceInfoRecord(m, info);
    UpdateAutoTunnelHostRecord(m, info);

    // If the global AutoTunnel NAT-T is not yet started, start it.
    if (!m->AutoTunnelNAT.clientContext)
    {
        m->AutoTunnelNAT.clientCallback   = AutoTunnelNATCallback;
        m->AutoTunnelNAT.clientContext    = (void*)1; // Means AutoTunnelNAT Traversal is active;
        m->AutoTunnelNAT.Protocol         = NATOp_MapUDP;
        m->AutoTunnelNAT.IntPort          = IPSECPort;
        m->AutoTunnelNAT.RequestedPort    = IPSECPort;
        m->AutoTunnelNAT.NATLease         = 0;
        mStatus err = mDNS_StartNATOperation_internal(m, &m->AutoTunnelNAT);
        if (err) LogMsg("StartServerTunnel: error %d starting NAT mapping", err);
    }
}

mDNSlocal mStatus AutoTunnelSetKeys(ClientTunnel *tun, mDNSBool AddNew)
{
    mDNSv6Addr loc_outer6;
    mDNSv6Addr rmt_outer6;

    // When we are tunneling over IPv6 Relay address, the port number is zero
    if (mDNSIPPortIsZero(tun->rmt_outer_port))
    {
        loc_outer6 = tun->loc_outer6;
        rmt_outer6 = tun->rmt_outer6;
    }
    else
    {
        loc_outer6 = zerov6Addr;
        loc_outer6.b[0] = tun->loc_outer.b[0];
        loc_outer6.b[1] = tun->loc_outer.b[1];
        loc_outer6.b[2] = tun->loc_outer.b[2];
        loc_outer6.b[3] = tun->loc_outer.b[3];

        rmt_outer6 = zerov6Addr;
        rmt_outer6.b[0] = tun->rmt_outer.b[0];
        rmt_outer6.b[1] = tun->rmt_outer.b[1];
        rmt_outer6.b[2] = tun->rmt_outer.b[2];
        rmt_outer6.b[3] = tun->rmt_outer.b[3];
    }

    return(mDNSAutoTunnelSetKeys(AddNew ? kmDNSAutoTunnelSetKeysReplace : kmDNSAutoTunnelSetKeysDelete, tun->loc_inner.b, loc_outer6.b, kRacoonPort, tun->rmt_inner.b, rmt_outer6.b, mDNSVal16(tun->rmt_outer_port), btmmprefix, SkipLeadingLabels(&tun->dstname, 1)));
}

// If the EUI-64 part of the IPv6 ULA matches, then that means the two addresses point to the same machine
#define mDNSSameClientTunnel(A,B) ((A)->l[2] == (B)->l[2] && (A)->l[3] == (B)->l[3])

mDNSlocal void ReissueBlockedQuestionWithType(mDNS *const m, domainname *d, mDNSBool success, mDNSu16 qtype)
{
    DNSQuestion *q = m->Questions;
    while (q)
    {
        if (q->NoAnswer == NoAnswer_Suspended && q->qtype == qtype && q->AuthInfo && q->AuthInfo->AutoTunnel && SameDomainName(&q->qname, d))
        {
            LogInfo("Restart %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
            mDNSQuestionCallback *tmp = q->QuestionCallback;
            q->QuestionCallback = AutoTunnelCallback;   // Set QuestionCallback to suppress another call back to AddNewClientTunnel
            mDNS_StopQuery(m, q);
            mDNS_StartQuery(m, q);
            q->QuestionCallback = tmp;                  // Restore QuestionCallback back to the real value
            if (!success) q->NoAnswer = NoAnswer_Fail;
            // When we call mDNS_StopQuery, it's possible for other subordinate questions like the GetZoneData query to be cancelled too.
            // In general we have to assume that the question list might have changed in arbitrary ways.
            // This code is itself called from a question callback, so the m->CurrentQuestion mechanism is
            // already in use. The safest solution is just to go back to the start of the list and start again.
            // In principle this sounds like an n^2 algorithm, but in practice we almost always activate
            // just one suspended question, so it's really a 2n algorithm.
            q = m->Questions;
        }
        else
            q = q->next;
    }
}

mDNSlocal void ReissueBlockedQuestions(mDNS *const m, domainname *d, mDNSBool success)
{
    // 1. We deliberately restart AAAA queries before A queries, because in the common case where a BTTM host has
    //    a v6 address but no v4 address, we prefer the caller to get the positive AAAA response before the A NXDOMAIN.
    // 2. In the case of AAAA queries, if our tunnel setup failed, then we return a deliberate failure indication to the caller --
    //    even if the name does have a valid AAAA record, we don't want clients trying to connect to it without a properly encrypted tunnel.
    // 3. For A queries we never fabricate failures -- if a BTTM service is really using raw IPv4, then it doesn't need the IPv6 tunnel.
    ReissueBlockedQuestionWithType(m, d, success, kDNSType_AAAA);
    ReissueBlockedQuestionWithType(m, d, mDNStrue, kDNSType_A);
}

mDNSlocal void UnlinkAndReissueBlockedQuestions(mDNS *const m, ClientTunnel *tun, mDNSBool success)
{
    ClientTunnel **p = &m->TunnelClients;
    while (*p != tun && *p) p = &(*p)->next;
    if (*p) *p = tun->next;
    ReissueBlockedQuestions(m, &tun->dstname, success);
    LogInfo("UnlinkAndReissueBlockedQuestions: Disposing ClientTunnel %p", tun);
    freeL("ClientTunnel", tun);
}

mDNSlocal mDNSBool TunnelClientDeleteMatching(mDNS *const m, ClientTunnel *tun, mDNSBool v6Tunnel)
{
    ClientTunnel **p;
    mDNSBool needSetKeys = mDNStrue;

    p = &tun->next;
    while (*p)
    {
        // Is this a tunnel to the same host that we are trying to setup now?
        if (!mDNSSameClientTunnel(&(*p)->rmt_inner, &tun->rmt_inner)) p = &(*p)->next;
        else
        {
            ClientTunnel *old = *p;
            if (v6Tunnel)
            {
                if (!mDNSIPPortIsZero(old->rmt_outer_port)) { p = &old->next; continue; }
                LogInfo("TunnelClientDeleteMatching: Found existing IPv6 AutoTunnel for %##s %.16a", old->dstname.c, &old->rmt_inner);
                if (old->q.ThisQInterval >= 0)
                {
                    LogInfo("TunnelClientDeleteMatching: Stopping query on IPv6 AutoTunnel for %##s %.16a", old->dstname.c, &old->rmt_inner);
                    mDNS_StopQuery(m, &old->q);
                }
                else if (!mDNSSameIPv6Address((*p)->rmt_inner, tun->rmt_inner) ||
                         !mDNSSameIPv6Address(old->loc_inner, tun->loc_inner)   ||
                         !mDNSSameIPv6Address(old->loc_outer6, tun->loc_outer6) ||
                         !mDNSSameIPv6Address(old->rmt_outer6, tun->rmt_outer6))
                {
                    // Delete the old tunnel if the current tunnel to the same host does not have the same ULA or
                    // the other parameters of the tunnel are different
                    LogInfo("TunnelClientDeleteMatching: Deleting existing IPv6 AutoTunnel for %##s %.16a", old->dstname.c, &old->rmt_inner);
                    AutoTunnelSetKeys(old, mDNSfalse);
                }
                else
                {
                    // Reusing the existing tunnel means that we reuse the IPsec SAs and the policies. We delete the old
                    // as "tun" and "old" are identical
                    LogInfo("TunnelClientDeleteMatching: Reusing the existing IPv6 AutoTunnel for %##s %.16a", old->dstname.c,
                            &old->rmt_inner);
                    needSetKeys = mDNSfalse;
                }
            }
            else
            {
                if (mDNSIPPortIsZero(old->rmt_outer_port)) { p = &old->next; continue; }
                LogInfo("TunnelClientDeleteMatching: Found existing IPv4 AutoTunnel for %##s %.16a", old->dstname.c, &old->rmt_inner);
                if (old->q.ThisQInterval >= 0)
                {
                    LogInfo("TunnelClientDeleteMatching: Stopping query on IPv4 AutoTunnel for %##s %.16a", old->dstname.c, &old->rmt_inner);
                    mDNS_StopQuery(m, &old->q);
                }
                else if (!mDNSSameIPv6Address((*p)->rmt_inner, tun->rmt_inner) ||
                         !mDNSSameIPv6Address(old->loc_inner, tun->loc_inner)   ||
                         !mDNSSameIPv4Address(old->loc_outer, tun->loc_outer)   ||
                         !mDNSSameIPv4Address(old->rmt_outer, tun->rmt_outer)   ||
                         !mDNSSameIPPort(old->rmt_outer_port, tun->rmt_outer_port))
                {
                    // Delete the old tunnel if the current tunnel to the same host does not have the same ULA or
                    // the other parameters of the tunnel are different
                    LogInfo("TunnelClientDeleteMatching: Deleting existing IPv4 AutoTunnel for %##s %.16a", old->dstname.c, &old->rmt_inner);
                    AutoTunnelSetKeys(old, mDNSfalse);
                }
                else
                {
                    // Reusing the existing tunnel means that we reuse the IPsec SAs and the policies. We delete the old
                    // as "tun" and "old" are identical
                    LogInfo("TunnelClientDeleteMatching: Reusing the existing IPv4 AutoTunnel for %##s %.16a", old->dstname.c,
                            &old->rmt_inner);
                    needSetKeys = mDNSfalse;
                }
            }

            *p = old->next;
            LogInfo("TunnelClientDeleteMatching: Disposing ClientTunnel %p", old);
            freeL("ClientTunnel", old);
        }
    }
    return needSetKeys;
}

// v6Tunnel indicates whether to delete a tunnel whose outer header is IPv6. If false, outer IPv4
// tunnel will be deleted
mDNSlocal void TunnelClientDeleteAny(mDNS *const m, ClientTunnel *tun, mDNSBool v6Tunnel)
{
    ClientTunnel **p;

    p = &tun->next;
    while (*p)
    {
        // If there is more than one client tunnel to the same host, delete all of them.
        // We do this by just checking against the EUI64 rather than the full address
        if (!mDNSSameClientTunnel(&(*p)->rmt_inner, &tun->rmt_inner)) p = &(*p)->next;
        else
        {
            ClientTunnel *old = *p;
            if (v6Tunnel)
            {
                if (!mDNSIPPortIsZero(old->rmt_outer_port)) { p = &old->next; continue;}
                LogInfo("TunnelClientDeleteAny: Found existing IPv6 AutoTunnel for %##s %.16a", old->dstname.c, &old->rmt_inner);
            }
            else
            {
                if (mDNSIPPortIsZero(old->rmt_outer_port)) { p = &old->next; continue;}
                LogInfo("TunnelClientDeleteAny: Found existing IPv4 AutoTunnel for %##s %.16a", old->dstname.c, &old->rmt_inner);
            }
            if (old->q.ThisQInterval >= 0)
            {
                LogInfo("TunnelClientDeleteAny: Stopping query on AutoTunnel for %##s %.16a", old->dstname.c, &old->rmt_inner);
                mDNS_StopQuery(m, &old->q);
            }
            else
            {
                LogInfo("TunnelClientDeleteAny: Deleting existing AutoTunnel for %##s %.16a", old->dstname.c, &old->rmt_inner);
                AutoTunnelSetKeys(old, mDNSfalse);
            }
            *p = old->next;
            LogInfo("TunnelClientDeleteAny: Disposing ClientTunnel %p", old);
            freeL("ClientTunnel", old);
        }
    }
}

mDNSlocal void TunnelClientFinish(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer)
{
    mDNSBool needSetKeys = mDNStrue;
    ClientTunnel *tun = (ClientTunnel *)question->QuestionContext;
    mDNSBool v6Tunnel = mDNSfalse;
    DomainAuthInfo *info;

    // If the port is zero, then we have a relay address of the peer
    if (mDNSIPPortIsZero(tun->rmt_outer_port))
        v6Tunnel = mDNStrue;

    if (v6Tunnel)
    {
        LogInfo("TunnelClientFinish: Relay address %.16a", &answer->rdata->u.ipv6);
        tun->rmt_outer6 = answer->rdata->u.ipv6;
        tun->loc_outer6 = m->AutoTunnelRelayAddr;
    }
    else
    {
        LogInfo("TunnelClientFinish: SRV target address %.4a", &answer->rdata->u.ipv4);
        tun->rmt_outer = answer->rdata->u.ipv4;
        mDNSAddr tmpDst = { mDNSAddrType_IPv4, {{{0}}} };
        tmpDst.ip.v4 = tun->rmt_outer;
        mDNSAddr tmpSrc = zeroAddr;
        mDNSPlatformSourceAddrForDest(&tmpSrc, &tmpDst);
        if (tmpSrc.type == mDNSAddrType_IPv4) tun->loc_outer = tmpSrc.ip.v4;
        else tun->loc_outer = m->AdvertisedV4.ip.v4;
    }

    question->ThisQInterval = -1;       // So we know this tunnel setup has completed

    info = GetAuthInfoForName(m, &tun->dstname);
    if (!info)
    {
        LogMsg("TunnelClientFinish: Could not get AuthInfo for %##s", tun->dstname.c);
        ReissueBlockedQuestions(m, &tun->dstname, mDNSfalse);
        return;
    }
    
    tun->loc_inner = info->AutoTunnelInnerAddress;

    // If we found a v6Relay address for our peer, delete all the v4Tunnels for our peer and
    // look for existing tunnels to see whether they have the same information for our peer.
    // If not, delete them and need to create a new tunnel. If they are same, just use the
    // same tunnel. Do the similar thing if we found a v4Tunnel end point for our peer.
    TunnelClientDeleteAny(m, tun, !v6Tunnel);
    needSetKeys = TunnelClientDeleteMatching(m, tun, v6Tunnel);

    if (needSetKeys) LogInfo("TunnelClientFinish: New %s AutoTunnel for %##s %.16a", (v6Tunnel ? "IPv6" : "IPv4"), tun->dstname.c, &tun->rmt_inner);
    else LogInfo("TunnelClientFinish: Reusing exiting %s AutoTunnel for %##s %.16a", (v6Tunnel ? "IPv6" : "IPv4"), tun->dstname.c, &tun->rmt_inner);

    mStatus result = needSetKeys ? AutoTunnelSetKeys(tun, mDNStrue) : mStatus_NoError;
    static char msgbuf[32];
    mDNS_snprintf(msgbuf, sizeof(msgbuf), "Tunnel setup - %d", result);
    mDNSASLLog((uuid_t *)&m->asl_uuid, "autotunnel.config", result ? "failure" : "success", msgbuf, "");
    // Kick off any questions that were held pending this tunnel setup
    ReissueBlockedQuestions(m, &tun->dstname, (result == mStatus_NoError) ? mDNStrue : mDNSfalse);
}

mDNSexport void AutoTunnelCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
    ClientTunnel *tun = (ClientTunnel *)question->QuestionContext;
    DomainAuthInfo *info;

    LogInfo("AutoTunnelCallback tun %p AddRecord %d rdlength %d qtype %d", tun, AddRecord, answer->rdlength, question->qtype);

    if (!AddRecord) return;
    mDNS_StopQuery(m, question);

    // If we are looking up the AAAA record for _autotunnel6, don't consider it as failure.
    // The code below will look for _autotunnel._udp SRV record followed by A record
    if (tun->tc_state != TC_STATE_AAAA_PEER_RELAY && !answer->rdlength)
    {
        LogInfo("AutoTunnelCallback NXDOMAIN %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
        static char msgbuf[16];
        mDNS_snprintf(msgbuf, sizeof(msgbuf), "%s lookup", DNSTypeName(question->qtype));
        mDNSASLLog((uuid_t *)&m->asl_uuid, "autotunnel.config", "failure", msgbuf, "");
        UnlinkAndReissueBlockedQuestions(m, tun, mDNSfalse);
        return;
    }

    switch (tun->tc_state)
    {
    case TC_STATE_AAAA_PEER:
        if (question->qtype != kDNSType_AAAA)
        {
            LogMsg("AutoTunnelCallback: Bad question type %d in TC_STATE_AAAA_PEER", question->qtype);
        }
        info = GetAuthInfoForName(m, &tun->dstname);
        if (!info)
        {
            LogMsg("AutoTunnelCallback: Could not get AuthInfo for %##s", tun->dstname.c);
            UnlinkAndReissueBlockedQuestions(m, tun, mDNStrue);
            return;
        }
        if (mDNSSameIPv6Address(answer->rdata->u.ipv6, info->AutoTunnelInnerAddress))
        {
            LogInfo("AutoTunnelCallback: suppressing tunnel to self %.16a", &answer->rdata->u.ipv6);
            UnlinkAndReissueBlockedQuestions(m, tun, mDNStrue);
            return;
        }
        if (info && mDNSSameIPv6NetworkPart(answer->rdata->u.ipv6, info->AutoTunnelInnerAddress))
        {
            LogInfo("AutoTunnelCallback: suppressing tunnel to peer %.16a", &answer->rdata->u.ipv6);
            UnlinkAndReissueBlockedQuestions(m, tun, mDNStrue);
            return;
        }
        tun->rmt_inner = answer->rdata->u.ipv6;
        LogInfo("AutoTunnelCallback:TC_STATE_AAAA_PEER: dst host %.16a", &tun->rmt_inner);
        if (!mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddr))
        {
            LogInfo("AutoTunnelCallback: Looking up _autotunnel6 AAAA");
            tun->tc_state = TC_STATE_AAAA_PEER_RELAY;
            question->qtype = kDNSType_AAAA;
            AssignDomainName(&question->qname, (const domainname*) "\x0C" "_autotunnel6");
        }
        else
        {
            LogInfo("AutoTunnelCallback: Looking up _autotunnel._udp SRV");
            tun->tc_state = TC_STATE_SRV_PEER;
            question->qtype = kDNSType_SRV;
            AssignDomainName(&question->qname, (const domainname*) "\x0B" "_autotunnel" "\x04" "_udp");
        }
        AppendDomainName(&question->qname, &tun->dstname);
        mDNS_StartQuery(m, &tun->q);
        return;
    case TC_STATE_AAAA_PEER_RELAY:
        if (question->qtype != kDNSType_AAAA)
        {
            LogMsg("AutoTunnelCallback: Bad question type %d in TC_STATE_AAAA_PEER_RELAY", question->qtype);
        }
        // If it failed, look for the SRV record.
        if (!answer->rdlength)
        {
            LogInfo("AutoTunnelCallback: Looking up _autotunnel6 AAAA failed, trying SRV");
            tun->tc_state = TC_STATE_SRV_PEER;
            AssignDomainName(&question->qname, (const domainname*) "\x0B" "_autotunnel" "\x04" "_udp");
            AppendDomainName(&question->qname, &tun->dstname);
            question->qtype = kDNSType_SRV;
            mDNS_StartQuery(m, &tun->q);
            return;
        }
        TunnelClientFinish(m, question, answer);
        return;
    case TC_STATE_SRV_PEER:
        if (question->qtype != kDNSType_SRV)
        {
            LogMsg("AutoTunnelCallback: Bad question type %d in TC_STATE_SRV_PEER", question->qtype);
        }
        LogInfo("AutoTunnelCallback: SRV target name %##s", answer->rdata->u.srv.target.c);
        tun->tc_state = TC_STATE_ADDR_PEER;
        AssignDomainName(&tun->q.qname, &answer->rdata->u.srv.target);
        tun->rmt_outer_port = answer->rdata->u.srv.port;
        question->qtype = kDNSType_A;
        mDNS_StartQuery(m, &tun->q);
        return;
    case TC_STATE_ADDR_PEER:
        if (question->qtype != kDNSType_A)
        {
            LogMsg("AutoTunnelCallback: Bad question type %d in TC_STATE_ADDR_PEER", question->qtype);
        }
        TunnelClientFinish(m, question, answer);
        return;
    default:
        LogMsg("AutoTunnelCallback: Unknown question %p", question);
    }
}

// Must be called with the lock held
mDNSexport void AddNewClientTunnel(mDNS *const m, DNSQuestion *const q)
{
    ClientTunnel *p = mallocL("ClientTunnel", sizeof(ClientTunnel));
    if (!p) return;
    AssignDomainName(&p->dstname, &q->qname);
    p->MarkedForDeletion = mDNSfalse;
    p->loc_inner      = zerov6Addr;
    p->loc_outer      = zerov4Addr;
    p->loc_outer6     = zerov6Addr;
    p->rmt_inner      = zerov6Addr;
    p->rmt_outer      = zerov4Addr;
    p->rmt_outer6     = zerov6Addr;
    p->rmt_outer_port = zeroIPPort;
    p->tc_state = TC_STATE_AAAA_PEER;
    p->next = m->TunnelClients;
    m->TunnelClients = p;       // We intentionally build list in reverse order

    p->q.InterfaceID      = mDNSInterface_Any;
    p->q.flags            = 0;
    p->q.Target           = zeroAddr;
    AssignDomainName(&p->q.qname, &q->qname);
    p->q.qtype            = kDNSType_AAAA;
    p->q.qclass           = kDNSClass_IN;
    p->q.LongLived        = mDNSfalse;
    p->q.ExpectUnique     = mDNStrue;
    p->q.ForceMCast       = mDNSfalse;
    p->q.ReturnIntermed   = mDNStrue;
    p->q.SuppressUnusable = mDNSfalse;
    p->q.SearchListIndex  = 0;
    p->q.AppendSearchDomains = 0;
    p->q.RetryWithSearchDomains = mDNSfalse;
    p->q.TimeoutQuestion  = 0;
    p->q.WakeOnResolve    = 0;
    p->q.UseBrackgroundTrafficClass = mDNSfalse;
    p->q.ValidationRequired = 0;
    p->q.ValidatingResponse = 0;
    p->q.qnameOrig        = mDNSNULL;
    p->q.QuestionCallback = AutoTunnelCallback;
    p->q.QuestionContext  = p;

    LogInfo("AddNewClientTunnel start tun %p %##s (%s)%s", p, &q->qname.c, DNSTypeName(q->qtype), q->LongLived ? " LongLived" : "");
    mDNS_StartQuery_internal(m, &p->q);
}

#endif // APPLE_OSX_mDNSResponder

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - Power State & Configuration Change Management
#endif

mDNSlocal mStatus UpdateInterfaceList(mDNS *const m, mDNSs32 utc)
{
    mDNSBool foundav4           = mDNSfalse;
    mDNSBool foundav6           = mDNSfalse;
    struct ifaddrs *ifa         = myGetIfAddrs(1);
    struct ifaddrs *v4Loopback  = NULL;
    struct ifaddrs *v6Loopback  = NULL;
    char defaultname[64];
#ifndef NO_IPV6
    int InfoSocket              = socket(AF_INET6, SOCK_DGRAM, 0);
    if (InfoSocket < 3 && errno != EAFNOSUPPORT) LogMsg("UpdateInterfaceList: InfoSocket error %d errno %d (%s)", InfoSocket, errno, strerror(errno));
#endif

    while (ifa)
    {
#if LIST_ALL_INTERFACES
        if (ifa->ifa_addr->sa_family == AF_APPLETALK)
            LogMsg("UpdateInterfaceList: %5s(%d) Flags %04X Family %2d is AF_APPLETALK",
                   ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
        else if (ifa->ifa_addr->sa_family == AF_LINK)
            LogMsg("UpdateInterfaceList: %5s(%d) Flags %04X Family %2d is AF_LINK",
                   ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
        else if (ifa->ifa_addr->sa_family != AF_INET && ifa->ifa_addr->sa_family != AF_INET6)
            LogMsg("UpdateInterfaceList: %5s(%d) Flags %04X Family %2d not AF_INET (2) or AF_INET6 (30)",
                   ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
        if (!(ifa->ifa_flags & IFF_UP))
            LogMsg("UpdateInterfaceList: %5s(%d) Flags %04X Family %2d Interface not IFF_UP",
                   ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
        if (!(ifa->ifa_flags & IFF_MULTICAST))
            LogMsg("UpdateInterfaceList: %5s(%d) Flags %04X Family %2d Interface not IFF_MULTICAST",
                   ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
        if (ifa->ifa_flags & IFF_POINTOPOINT)
            LogMsg("UpdateInterfaceList: %5s(%d) Flags %04X Family %2d Interface IFF_POINTOPOINT",
                   ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
        if (ifa->ifa_flags & IFF_LOOPBACK)
            LogMsg("UpdateInterfaceList: %5s(%d) Flags %04X Family %2d Interface IFF_LOOPBACK",
                   ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
#endif

        if (ifa->ifa_addr->sa_family == AF_LINK)
        {
            struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr;
            if (sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == sizeof(m->PrimaryMAC) && mDNSSameEthAddress(&m->PrimaryMAC, &zeroEthAddr))
                mDNSPlatformMemCopy(m->PrimaryMAC.b, sdl->sdl_data + sdl->sdl_nlen, 6);
        }

        if (ifa->ifa_flags & IFF_UP && ifa->ifa_addr)
            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",
                           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
                // <rdar://problem/5492035> getifaddrs is returning invalid netmask family for fw0 and vmnet
                else if (ifa->ifa_netmask->sa_family != ifa->ifa_addr->sa_family && ifa->ifa_netmask->sa_family != 0)
                {
                    mDNSAddr ip;
                    SetupAddr(&ip, ifa->ifa_addr);
                    LogMsg("getifaddrs 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).
                else if ((int)if_nametoindex(ifa->ifa_name) <= 0)
                {
                    LogMsg("UpdateInterfaceList: if_nametoindex returned zero/negative value for %5s(%d)", ifa->ifa_name, if_nametoindex(ifa->ifa_name));
                }
                else
                {
                    // Make sure ifa_netmask->sa_family is set correctly
                    // <rdar://problem/5492035> getifaddrs is returning invalid netmask family for fw0 and vmnet
                    ifa->ifa_netmask->sa_family = ifa->ifa_addr->sa_family;
                    int ifru_flags6 = 0;
#ifndef NO_IPV6
                    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
                    if (ifa->ifa_addr->sa_family == AF_INET6 && InfoSocket >= 0)
                    {
                        struct in6_ifreq ifr6;
                        mDNSPlatformMemZero((char *)&ifr6, sizeof(ifr6));
                        strlcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name));
                        ifr6.ifr_addr = *sin6;
                        if (ioctl(InfoSocket, SIOCGIFAFLAG_IN6, &ifr6) != -1)
                            ifru_flags6 = ifr6.ifr_ifru.ifru_flags6;
                        verbosedebugf("%s %.16a %04X %04X", ifa->ifa_name, &sin6->sin6_addr, ifa->ifa_flags, ifru_flags6);
                    }
#endif
                    if (!(ifru_flags6 & (IN6_IFF_NOTREADY | IN6_IFF_DETACHED | IN6_IFF_DEPRECATED | IN6_IFF_TEMPORARY)))
                    {
                        if (ifa->ifa_flags & IFF_LOOPBACK)
                        {
                            if (ifa->ifa_addr->sa_family == AF_INET) v4Loopback = ifa;
#ifndef NO_IPV6
                            else if (sin6->sin6_addr.s6_addr[0] != 0xFD) v6Loopback = ifa;
#endif
                        }
                        else
                        {
                            NetworkInterfaceInfoOSX *i = AddInterfaceToList(m, ifa, utc);
                            if (i && MulticastInterface(i) && i->ifinfo.Advertise)
                            {
                                if (ifa->ifa_addr->sa_family == AF_INET) foundav4 = mDNStrue;
                                else foundav6 = mDNStrue;
                            }
                        }
                    }
                }
            }
        ifa = ifa->ifa_next;
    }

    // For efficiency, we don't register a loopback interface when other interfaces of that family are available and advertising
    if (!foundav4 && v4Loopback) AddInterfaceToList(m, v4Loopback, utc);
    if (!foundav6 && v6Loopback) AddInterfaceToList(m, 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 USE_V6_ONLY_WHEN_NO_ROUTABLE_V4
            txrx = txrx && ((i->ifinfo.ip.type == mDNSAddrType_IPv4) || !FindRoutableIPv4(m, i->scope_id));
#endif
            if (i->ifinfo.McastTxRx != txrx)
            {
                i->ifinfo.McastTxRx = txrx;
                i->Exists = 2; // State change; need to deregister and reregister this interface
            }
        }

#ifndef NO_IPV6
    if (InfoSocket >= 0) close(InfoSocket);
#endif

    mDNS_snprintf(defaultname, sizeof(defaultname), "%.*s-%02X%02X%02X%02X%02X%02X", HINFO_HWstring_prefixlen, HINFO_HWstring,
                  m->PrimaryMAC.b[0], m->PrimaryMAC.b[1], m->PrimaryMAC.b[2], m->PrimaryMAC.b[3], m->PrimaryMAC.b[4], m->PrimaryMAC.b[5]);

    // Set up the nice label
    domainlabel nicelabel;
    nicelabel.c[0] = 0;
    GetUserSpecifiedFriendlyComputerName(&nicelabel);
    if (nicelabel.c[0] == 0)
    {
        debugf("Couldn’t read user-specified Computer Name; using default “%s” instead", defaultname);
        MakeDomainLabelFromLiteralString(&nicelabel, defaultname);
    }

    // Set up the RFC 1034-compliant label
    domainlabel hostlabel;
    hostlabel.c[0] = 0;
    GetUserSpecifiedLocalHostName(&hostlabel);
    if (hostlabel.c[0] == 0)
    {
        debugf("Couldn’t read user-specified Local Hostname; using default “%s.local” instead", defaultname);
        MakeDomainLabelFromLiteralString(&hostlabel, defaultname);
    }

    mDNSBool namechange = mDNSfalse;

    // We use a case-sensitive comparison here because even though changing the capitalization
    // of the name alone is not significant to DNS, it's still a change from the user's point of view
    if (SameDomainLabelCS(m->p->usernicelabel.c, nicelabel.c))
        debugf("Usernicelabel (%#s) unchanged since last time; not changing m->nicelabel (%#s)", m->p->usernicelabel.c, m->nicelabel.c);
    else
    {
        if (m->p->usernicelabel.c[0])   // Don't show message first time through, when we first read name from prefs on boot
            LogMsg("User updated Computer Name from “%#s” to “%#s”", m->p->usernicelabel.c, nicelabel.c);
        m->p->usernicelabel = m->nicelabel = nicelabel;
        namechange = mDNStrue;
    }

    if (SameDomainLabelCS(m->p->userhostlabel.c, hostlabel.c))
        debugf("Userhostlabel (%#s) unchanged since last time; not changing m->hostlabel (%#s)", m->p->userhostlabel.c, m->hostlabel.c);
    else
    {
        if (m->p->userhostlabel.c[0])   // Don't show message first time through, when we first read name from prefs on boot
            LogMsg("User updated Local Hostname from “%#s” to “%#s”", m->p->userhostlabel.c, hostlabel.c);
        m->p->userhostlabel = m->hostlabel = hostlabel;
        mDNS_SetFQDN(m);
        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
    {
        DomainAuthInfo *info;
        for (info = m->AuthInfoList; info; info = info->next)
            if (info->AutoTunnel) AutoTunnelHostNameChanged(m, info);
    }
#endif // APPLE_OSX_mDNSResponder

    return(mStatus_NoError);
}

// Returns number of leading one-bits in mask: 0-32 for IPv4, 0-128 for IPv6
// Returns -1 if all the one-bits are not contiguous
mDNSlocal int CountMaskBits(mDNSAddr *mask)
{
    int i = 0, bits = 0;
    int bytes = mask->type == mDNSAddrType_IPv4 ? 4 : mask->type == mDNSAddrType_IPv6 ? 16 : 0;
    while (i < bytes)
    {
        mDNSu8 b = mask->ip.v6.b[i++];
        while (b & 0x80) { bits++; b <<= 1; }
        if (b) return(-1);
    }
    while (i < bytes) if (mask->ip.v6.b[i++]) return(-1);
    return(bits);
}

// returns count of non-link local V4 addresses registered
mDNSlocal int SetupActiveInterfaces(mDNS *const m, mDNSs32 utc)
{
    NetworkInterfaceInfoOSX *i;
    int count = 0;
    for (i = m->p->InterfaceList; i; i = i->next)
        if (i->Exists)
        {
            NetworkInterfaceInfo *const n = &i->ifinfo;
            NetworkInterfaceInfoOSX *primary = SearchForInterfaceByName(m, i->ifinfo.ifname, AAAA_OVER_V4 ? AF_UNSPEC : i->sa_family);
            if (!primary) LogMsg("SetupActiveInterfaces ERROR! SearchForInterfaceByName didn't find %s", i->ifinfo.ifname);

            if (i->Registered && i->Registered != primary)  // Sanity check
            {
                LogMsg("SetupActiveInterfaces ERROR! n->Registered %p != primary %p", i->Registered, primary);
                i->Registered = mDNSNULL;
            }

            if (!i->Registered)
            {
                // 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
                //

                i->Registered = primary;

                // If i->LastSeen == utc, then this is a brand-new interface, just created, or an interface that never went away.
                // If i->LastSeen != utc, then this is an old interface, previously seen, that went away for (utc - i->LastSeen) seconds.
                // If the interface is an old one that went away and came back in less than a minute, then we're in a flapping scenario.
                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
                // 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.
                if (strncmp(i->ifinfo.ifname, "p2p", 3) == 0)
                {
                    LogInfo("SetupActiveInterfaces: P2P %s interface registering %s %s", i->ifinfo.ifname,
                            i->Flashing               ? " (Flashing)"  : "",
                            i->Occulting              ? " (Occulting)" : "");
                    mDNS_RegisterInterface(m, n, 0);
                }
                else
                {
                    mDNS_RegisterInterface(m, n, i->Flashing && i->Occulting);
                }

                if (!mDNSAddressIsLinkLocal(&n->ip)) count++;
                LogInfo("SetupActiveInterfaces:   Registered    %5s(%lu) %.6a InterfaceID %p(%p), primary %p, %#a/%d%s%s%s",
                        i->ifinfo.ifname, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID, i, primary, &n->ip, CountMaskBits(&n->mask),
                        i->Flashing        ? " (Flashing)"  : "",
                        i->Occulting       ? " (Occulting)" : "",
                        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);
                else
                {
                    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 this is our *first* IPv4 instance for this interface name, we need to do a IP_DROP_MEMBERSHIP first,
                        // before trying to join the group, to clear out stale kernel state which may be lingering.
                        // In particular, this happens with removable network interfaces like USB Ethernet adapters -- the kernel has stale state
                        // from the last time the USB Ethernet adapter was connected, and part of the kernel thinks we've already joined the group
                        // on that interface (so we get EADDRINUSE when we try to join again) but a different part of the kernel thinks we haven't
                        // joined the group (so we receive no multicasts). Doing an IP_DROP_MEMBERSHIP before joining seems to flush the stale state.
                        // Also, trying to make the code leave the group when the adapter is removed doesn't work either,
                        // because by the time we get the configuration change notification, the interface is already gone,
                        // so attempts to unsubscribe fail with EADDRNOTAVAIL (errno 49 "Can't assign requested address").
                        // <rdar://problem/5585972> IP_ADD_MEMBERSHIP fails for previously-connected removable interfaces
                        if (SearchForInterfaceByName(m, i->ifinfo.ifname, AF_INET) == i)
                        {
                            LogInfo("SetupActiveInterfaces: %5s(%lu) Doing precautionary 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));
                        }

                        LogInfo("SetupActiveInterfaces: %5s(%lu) joining IPv4 mcast group %.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_ADD_MEMBERSHIP, &imr, sizeof(imr));
                        // Joining same group twice can give "Address already in use" error -- no need to report that
                        if (err < 0 && (errno != EADDRINUSE))
                            LogMsg("setsockopt - IP_ADD_MEMBERSHIP error %d errno %d (%s) group %.4a on %.4a", err, errno, strerror(errno), &imr.imr_multiaddr, &imr.imr_interface);
                    }
#ifndef NO_IPV6
                    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 precautionary 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);
                        }

                        LogInfo("SetupActiveInterfaces: %5s(%lu) joining IPv6 mcast group %.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_JOIN_GROUP, &i6mr, sizeof(i6mr));
                        // Joining same group twice can give "Address already in use" error -- no need to report that
                        if (err < 0 && (errno != EADDRINUSE))
                            LogMsg("setsockopt - IPV6_JOIN_GROUP error %d errno %d (%s) group %.16a on %u", err, errno, strerror(errno), &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);
                    }
#endif
                }
            }
        }

    return count;
}

mDNSlocal void MarkAllInterfacesInactive(mDNS *const m, mDNSs32 utc)
{
    NetworkInterfaceInfoOSX *i;
    for (i = m->p->InterfaceList; i; i = i->next)
    {
        if (i->Exists) i->LastSeen = utc;
        i->Exists = mDNSfalse;
    }
}

// returns count of non-link local V4 addresses deregistered
mDNSlocal int ClearInactiveInterfaces(mDNS *const m, mDNSs32 utc)
{
    // First pass:
    // If an interface is going away, then deregister this from the mDNSCore.
    // We also have to deregister it if the primary interface that it's using for its InterfaceID is going away.
    // We have to do this because mDNSCore will use that InterfaceID when sending packets, and if the memory
    // it refers to has gone away we'll crash.
    NetworkInterfaceInfoOSX *i;
    int count = 0;
    for (i = m->p->InterfaceList; i; i = i->next)
    {
        // If this interface is no longer active, or its InterfaceID is changing, deregister it
        NetworkInterfaceInfoOSX *primary = SearchForInterfaceByName(m, i->ifinfo.ifname, AAAA_OVER_V4 ? AF_UNSPEC : i->sa_family);
        if (i->Registered)
            if (i->Exists == 0 || i->Exists == 2 || i->Registered != primary)
            {
                i->Flashing = !(i->ifa_flags & IFF_LOOPBACK) && (utc - i->AppearanceTime < 60);
                LogInfo("ClearInactiveInterfaces: Deregistering %5s(%lu) %.6a InterfaceID %p(%p), primary %p, %#a/%d%s%s%s",
                        i->ifinfo.ifname, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID, i, primary,
                        &i->ifinfo.ip, CountMaskBits(&i->ifinfo.mask),
                        i->Flashing               ? " (Flashing)"  : "",
                        i->Occulting              ? " (Occulting)" : "",
                        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
                // 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.
                if (strncmp(i->ifinfo.ifname, "p2p", 3) == 0)
                {
                    LogInfo("ClearInactiveInterfaces: P2P %s interface deregistering %s %s", i->ifinfo.ifname,
                            i->Flashing               ? " (Flashing)"  : "",
                            i->Occulting              ? " (Occulting)" : "");
                    mDNS_DeregisterInterface(m, &i->ifinfo, 0);
                }
                else
                {
                    mDNS_DeregisterInterface(m, &i->ifinfo, i->Flashing && i->Occulting);
                }
                if (!mDNSAddressIsLinkLocal(&i->ifinfo.ip)) count++;
                i->Registered = mDNSNULL;
                // 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 it's not registered and we should not call mDNS_DeregisterInterface() on it.

                // Caution: If we ever decide to add code here to leave the multicast group, we need to make sure that this
                // is the LAST representative of this physical interface, or we'll unsubscribe from the group prematurely.
            }
    }

    // Second pass:
    // Now that everything that's going to deregister has done so, we can clean up and free the memory
    NetworkInterfaceInfoOSX **p = &m->p->InterfaceList;
    while (*p)
    {
        i = *p;
        // If no longer active, delete interface from list and free memory
        if (!i->Exists)
        {
            if (i->LastSeen == utc) i->LastSeen = utc - 1;
            mDNSBool delete = (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,
                    i->ifinfo.InterfaceActive ? " (Primary)" : "");
#if APPLE_OSX_mDNSResponder
            if (i->BPF_fd >= 0) CloseBPF(i);
#endif // APPLE_OSX_mDNSResponder
            if (delete)
            {
                *p = i->next;
                freeL("NetworkInterfaceInfoOSX", i);
                continue;   // After deleting this object, don't want to do the "p = &i->next;" thing at the end of the loop
            }
        }
        p = &i->next;
    }
    return count;
}

mDNSlocal void AppendDNameListElem(DNameListElem ***List, mDNSu32 uid, domainname *name)
{
    DNameListElem *dnle = (DNameListElem*) mallocL("DNameListElem/AppendDNameListElem", sizeof(DNameListElem));
    if (!dnle) LogMsg("ERROR: AppendDNameListElem: memory exhausted");
    else
    {
        dnle->next = mDNSNULL;
        dnle->uid  = uid;
        AssignDomainName(&dnle->name, name);
        **List = dnle;
        *List = &dnle->next;
    }
}

mDNSlocal int compare_dns_configs(const void *aa, const void *bb)
{
    dns_resolver_t *a = *(dns_resolver_t**)aa;
    dns_resolver_t *b = *(dns_resolver_t**)bb;

    return (a->search_order < b->search_order) ? -1 : (a->search_order == b->search_order) ? 0 : 1;
}

mDNSlocal void UpdateSearchDomainHash(mDNS *const m, MD5_CTX *sdc, char *domain, mDNSInterfaceID InterfaceID)
{
    char *buf = ".";
    mDNSu32 scopeid = 0;
    char ifid_buf[16];

    if (domain)
        buf = domain;
    //
    // Hash the search domain name followed by the InterfaceID.
    // As we have scoped search domains, we also included InterfaceID. If either of them change,
    // we will detect it. Even if the order of them change, we will detect it.
    //
    // Note: We have to handle a few of these tricky cases.
    //
    // 1) Current: com, apple.com Changing to: comapple.com
    // 2) Current: a.com,b.com Changing to a.comb.com
    // 3) Current: a.com,b.com (ifid 8), Changing to a.com8b.com (ifid 8)
    // 4) Current: a.com (ifid 12), Changing to a.com1 (ifid: 2)
    //
    // There are more variants of the above. The key thing is if we include the null in each case
    // at the end of name and the InterfaceID, it will prevent a new name (which can't include
    // NULL as part of the name) to be mistakenly thought of as a old name.

    scopeid = mDNSPlatformInterfaceIndexfromInterfaceID(m, InterfaceID, mDNStrue);
    // mDNS_snprintf always null terminates
    if (mDNS_snprintf(ifid_buf, sizeof(ifid_buf), "%u", scopeid) >= sizeof(ifid_buf))
        LogMsg("UpdateSearchDomainHash: mDNS_snprintf failed for scopeid %u", scopeid);

    LogInfo("UpdateSearchDomainHash: buf %s, ifid_buf %s", buf, ifid_buf);
    MD5_Update(sdc, buf, strlen(buf) + 1);
    MD5_Update(sdc, ifid_buf, strlen(ifid_buf) + 1);
}

mDNSlocal void FinalizeSearchDomainHash(mDNS *const m, MD5_CTX *sdc)
{
    mDNSu8 md5_hash[MD5_LEN];

    MD5_Final(md5_hash, sdc);

    if (memcmp(md5_hash, m->SearchDomainsHash, MD5_LEN))
    {
        // If the hash is different, either the search domains have changed or
        // the ordering between them has changed. Restart the questions that
        // would be affected by this.
        LogInfo("FinalizeSearchDomains: The hash is different");
        memcpy(m->SearchDomainsHash, md5_hash, MD5_LEN);
        RetrySearchDomainQuestions(m);
    }
    else { LogInfo("FinalizeSearchDomains: The hash is same"); }
}

// ConfigResolvers is called twice - once to parse the "scoped_resolver" list and second time to parse the "resolver" list.
// "scoped_resolver" has entries that should only be used for "scoped_questions" (for questions that specify an interface index
// q->InterfaceID) and "resolver" entries should only be used for non-scoped questions. Entries in either of the list can specify
// an ifindex. This means that the dns query should be scoped to that interface when sent out on the wire. The flag value
// "DNS_RESOLVER_FLAGS_SCOPED" itself appears only in "scoped" list of resolvers.
//
// Before "scoped_resolver" was introduced, the entries in "resolver" list can contain options like "interface=en0" which
// was meant to scope the query (non-scoped queries) to a specific interface. We still support this option. On top of that,
// we also support a new way of specifying the interface index as described above.
mDNSlocal void ConfigResolvers(mDNS *const m, dns_config_t *config, mDNSBool scope, mDNSBool setsearch, mDNSBool setservers, MD5_CTX *sdc, mDNSu16 resGroupID)
{
    int i, j;
    domainname d;
#if DNSINFO_VERSION >= 20091104
    dns_resolver_t **resolver = scope ? config->scoped_resolver : config->resolver;
    int nresolvers = scope ? config->n_scoped_resolver : config->n_resolver;
#else
    (void) scope; // unused
    dns_resolver_t **resolver = config->resolver;
    int nresolvers = config->n_resolver;
#endif

    if (setsearch && !scope && nresolvers)
    {
        // Due to the vagaries of Apple's SystemConfiguration and dnsinfo.h APIs, if there are no search domains
        // listed, then you're supposed to interpret the "domain" field as also being the search domain, but if
        // there *are* search domains listed, then you're supposed to ignore the "domain" field completely and
        // instead use the search domain list as the sole authority for what domains to search and in what order
        // (and the domain from the "domain" field will also appear somewhere in that list).
        // Also, all search domains get added to the search list for resolver[0], so the domains and/or
        // search lists for other resolvers in the list need to be ignored.
        //
        // Note: Starting DNSINFO_VERSION 20091104, search list is present only in the first resolver (resolver 0).
        // i.e., n_search for the first resolver is always non-zero. We don't guard it with #ifs for better readability

        if (resolver[0]->n_search == 0)
        {
            LogInfo("ConfigResolvers: (%s) configuring zeroth domain as search list %s", scope ? "Scoped" : "Non-scoped", resolver[0]->domain);
            UpdateSearchDomainHash(m, sdc, resolver[0]->domain, NULL);
            mDNS_AddSearchDomain_CString(resolver[0]->domain, mDNSNULL);
        }
        else
        {
            for (i = 0; i < resolver[0]->n_search; i++)
            {
                LogInfo("ConfigResolvers: (%s) configuring search list %s", scope ? "Scoped" : "Non-scoped", resolver[0]->search[i]);
                UpdateSearchDomainHash(m, sdc, resolver[0]->search[i], NULL);
                mDNS_AddSearchDomain_CString(resolver[0]->search[i], mDNSNULL);
            }
        }
    }

    // scoped search domains are set below. If neither scoped nor setting servers, we have nothing to do
    if (!scope && !setservers) return;

    // For the "default" resolver ("resolver #1") the "domain" value is bogus and we need to ignore it.
    // e.g. the default resolver's "domain" value might say "apple.com", which indicates that this resolver
    // is only for names that fall under "apple.com", but that's not correct. Actually the default resolver is
    // for all names not covered by a more specific resolver (i.e. its domain should be ".", the root domain).
    //
    // Note: Starting DNSINFO_VERSION 20091104, domain value of this first resolver (resolver 0) is always NULL.
    // We don't guard it with #ifs for better readability
    //
    if ((nresolvers != 0) && resolver[0]->domain)
        resolver[0]->domain[0] = 0; // don't stop pointing at the memory, just change the first byte

    qsort(resolver, nresolvers, sizeof(dns_resolver_t*), compare_dns_configs);

    for (i = 0; i < nresolvers; i++)
    {
        int n;
        dns_resolver_t *r = resolver[i];
        mDNSInterfaceID interface = mDNSInterface_Any;
        int disabled = 0;

        LogInfo("ConfigResolvers: %s resolver[%d] domain %s n_nameserver %d", scope ? "Scoped" : "", i, r->domain, r->n_nameserver);

        // On Tiger, dnsinfo entries for mDNS domains have port 5353, the mDNS port.  Ignore them.
        // Note: Unlike the BSD Sockets APIs (where TCP and UDP port numbers are universally in network byte order)
        // in Apple's "dnsinfo.h" API the port number is declared to be a "uint16_t in host byte order"
        // We also don't need to do any more work if there are no nameserver addresses
        if (r->port == 5353 || r->n_nameserver == 0)
        {
            char *opt = r->options;
            if (opt && !strncmp(opt, "mdns", strlen(opt)))
            {
                if (!MakeDomainNameFromDNSNameString(&d, r->domain))
                { LogMsg("ConfigResolvers: config->resolver[%d] bad domain %s", i, r->domain); continue; }
                mDNS_AddMcastResolver(m, &d, interface, r->timeout);
            }
            continue;
        }


        if (!r->domain || !*r->domain) d.c[0] = 0;
        else if (!MakeDomainNameFromDNSNameString(&d, r->domain))
        { LogMsg("ConfigResolvers: config->resolver[%d] bad domain %s", i, r->domain); continue; }

        // DNS server option parsing
        if (r->options != NULL)
        {
            char *nextOption = r->options;
            char *currentOption = NULL;
            while ((currentOption = strsep(&nextOption, " ")) != NULL && currentOption[0] != 0)
            {
                // The option may be in the form of interface=xxx where xxx is an interface name.
                if (strncmp(currentOption, kInterfaceSpecificOption, sizeof(kInterfaceSpecificOption) - 1) == 0)
                {
                    NetworkInterfaceInfoOSX *ni;
                    char ifname[IF_NAMESIZE+1];
                    mDNSu32 ifindex = 0;
                    // If something goes wrong finding the interface, create the server entry anyhow but mark it as disabled.
                    // This allows us to block these special queries from going out on the wire.
                    strlcpy(ifname, currentOption + sizeof(kInterfaceSpecificOption)-1, sizeof(ifname));
                    ifindex = if_nametoindex(ifname);
                    if (ifindex == 0) { disabled = 1; LogMsg("ConfigResolvers: RegisterSplitDNS interface specific - interface %s not found", ifname); continue; }
                    LogInfo("ConfigResolvers: interface specific entry: %s on %s (%d)", r->domain, ifname, ifindex);
                    // Find the interface. Can't use mDNSPlatformInterfaceIDFromInterfaceIndex
                    // because that will call mDNSMacOSXNetworkChanged if the interface doesn't exist
                    for (ni = m->p->InterfaceList; ni; ni = ni->next)
                        if (ni->ifinfo.InterfaceID && ni->scope_id == ifindex) break;
                    if (ni != NULL) interface = ni->ifinfo.InterfaceID;
                    if (interface == mDNSNULL)
                    {
                        disabled = 1;
                        LogMsg("ConfigResolvers: RegisterSplitDNS interface specific - index %d (%s) not found", ifindex, ifname);
                        continue;
                    }
                }
            }
        }

        // flags and if_index are defined only from this DNSINFO_VERSION onwards.
        // Parse the interface index if we have not already parsed one above.
#if DNSINFO_VERSION >= 20091104
        if ((interface == mDNSInterface_Any) && (r->if_index != 0))
        {
            NetworkInterfaceInfoOSX *ni;
            interface = mDNSNULL;
            for (ni = m->p->InterfaceList; ni; ni = ni->next)
                if (ni->ifinfo.InterfaceID && ni->scope_id == r->if_index) break;
            if (ni != NULL) interface = ni->ifinfo.InterfaceID;
            if (interface == mDNSNULL)
            {
                disabled = 1;
                LogMsg("ConfigResolvers: interface specific index %d not found", r->if_index);
                continue;
            }
        }
#endif

        if (setsearch)
        {
            // For non-scoped resolvers unlike scoped resolvers, only zeroth resolver has search lists if any. For scoped
            // resolvers, we need to parse all the entries.
            if (scope)
            {
                for (j = 0; j < resolver[i]->n_search; j++)
                {
                    LogInfo("ConfigResolvers: (%s) configuring search list %s, Interface %p", scope ? "Scoped" : "Non-scoped", resolver[i]->search[j], interface);
                    UpdateSearchDomainHash(m, sdc, resolver[i]->search[j], interface);
                    mDNS_AddSearchDomain_CString(resolver[i]->search[j], interface);
                }
                // Parse other scoped resolvers for search lists
                if (!setservers) continue;
            }
        }

        // Each scoped resolver gets its own ID (i.e., they are in their own group) so that responses from the
        // scoped resolver are not used by other non-scoped or scoped resolvers.
        if (scope) resGroupID++;

        for (n = 0; n < r->n_nameserver; n++)
            if (r->nameserver[n]->sa_family == AF_INET || r->nameserver[n]->sa_family == AF_INET6)
            {
                mDNSAddr saddr;
                // mDNSAddr saddr = { mDNSAddrType_IPv4, { { { 192, 168, 1, 1 } } } }; // for testing
                if (SetupAddr(&saddr, r->nameserver[n])) LogMsg("RegisterSplitDNS: bad IP address");
                else
                {
                    mDNSBool cellIntf = mDNSfalse;
                    mDNSBool scopedDNS = mDNSfalse;
                    DNSServer *s;
#if DNSINFO_VERSION >= 20091104
                    // By setting scoped, this DNSServer can only be picked if the right interfaceID
                    // is given in the question.
                    if (scope && (r->flags & DNS_RESOLVER_FLAGS_SCOPED) && (interface == mDNSNULL))
                        LogMsg("ConfigResolvers: ERROR: scoped is set but if_index %d is invalid for DNSServer %#a:%d",
                               r->if_index, &saddr, mDNSVal16(r->port ? mDNSOpaque16fromIntVal(r->port) : UnicastDNSPort));
                    else
                        scopedDNS = (scope && (r->flags & DNS_RESOLVER_FLAGS_SCOPED)) ? mDNStrue : mDNSfalse;
#endif
#if (DNSINFO_VERSION >= 20110420) && TARGET_OS_IPHONE
                    cellIntf = r->reach_flags & kSCNetworkReachabilityFlagsIsWWAN;
#endif
                    // The timeout value is for all the DNS servers in a given resolver, hence we pass
                    // the timeout value only for the first DNSServer. If we don't have a value in the
                    // resolver, then use the core's default value
                    //
                    // Note: this assumes that when the core picks a list of DNSServers for a question,
                    // it takes the sum of all the timeout values for all DNS servers. By doing this, it
                    // tries all the DNS servers in a specified timeout
                    s = mDNS_AddDNSServer(m, &d, interface, &saddr, r->port ? mDNSOpaque16fromIntVal(r->port) : UnicastDNSPort, scopedDNS,
                                          (n == 0 ? (r->timeout ? r->timeout : DEFAULT_UDNS_TIMEOUT) : 0), cellIntf, resGroupID);
                    if (s)
                    {
                        if (disabled) s->teststate = DNSServer_Disabled;
                        LogInfo("ConfigResolvers: DNS server %#a:%d for domain %##s from slot %d, %d",
                                &s->addr, mDNSVal16(s->port), d.c, i, n);
                    }
                }
            }
    }
}

mDNSexport void mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains, DNameListElem **BrowseDomains)
{
    int i;
    char buf[MAX_ESCAPED_DOMAIN_NAME];  // Max legal C-string name, including terminating NUL
    domainname d;
    MD5_CTX sdc;    // search domain context
    static mDNSu16 resolverGroupID = 0;

    // Need to set these here because we need to do this even if SCDynamicStoreCreate() or SCDynamicStoreCopyValue() below don't succeed
    if (fqdn) fqdn->c[0]      = 0;
    if (RegDomains   ) *RegDomains     = NULL;
    if (BrowseDomains) *BrowseDomains  = NULL;

    LogInfo("mDNSPlatformSetDNSConfig:%s%s%s%s%s",
            setservers    ? " setservers"    : "",
            setsearch     ? " setsearch"     : "",
            fqdn          ? " fqdn"          : "",
            RegDomains    ? " RegDomains"    : "",
            BrowseDomains ? " BrowseDomains" : "");

    if (setsearch) MD5_Init(&sdc);

    // Add the inferred address-based configuration discovery domains
    // (should really be in core code I think, not platform-specific)
    if (setsearch)
    {
        struct ifaddrs *ifa = mDNSNULL;
        struct sockaddr_in saddr;
        mDNSPlatformMemZero(&saddr, sizeof(saddr));
        saddr.sin_len = sizeof(saddr);
        saddr.sin_family = AF_INET;
        saddr.sin_port = 0;
        saddr.sin_addr.s_addr = *(in_addr_t *)&m->Router.ip.v4;

        // Don't add any reverse-IP search domains if doing the WAB bootstrap queries would cause dial-on-demand connection initiation
        if (!AddrRequiresPPPConnection((struct sockaddr *)&saddr)) ifa =  myGetIfAddrs(1);

        while (ifa)
        {
            mDNSAddr a, n;
            if (ifa->ifa_addr->sa_family == AF_INET &&
                ifa->ifa_netmask                    &&
                !(ifa->ifa_flags & IFF_LOOPBACK)    &&
                !SetupAddr(&a, ifa->ifa_addr)       &&
                !mDNSv4AddressIsLinkLocal(&a.ip.v4)  )
            {
                // Apparently it's normal for the sa_family of an ifa_netmask to sometimes be incorrect, so we explicitly fix it here before calling SetupAddr
                // <rdar://problem/5492035> getifaddrs is returning invalid netmask family for fw0 and vmnet
                ifa->ifa_netmask->sa_family = ifa->ifa_addr->sa_family;     // Make sure ifa_netmask->sa_family is set correctly
                SetupAddr(&n, ifa->ifa_netmask);
                // Note: This is reverse order compared to a normal dotted-decimal IP address, so we can't use our customary "%.4a" format code
                mDNS_snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa.", a.ip.v4.b[3] & n.ip.v4.b[3],
                              a.ip.v4.b[2] & n.ip.v4.b[2],
                              a.ip.v4.b[1] & n.ip.v4.b[1],
                              a.ip.v4.b[0] & n.ip.v4.b[0]);
                UpdateSearchDomainHash(m, &sdc, buf, NULL);
                mDNS_AddSearchDomain_CString(buf, mDNSNULL);
            }
            ifa = ifa->ifa_next;
        }
    }

#ifndef MDNS_NO_DNSINFO
    if (setservers || setsearch)
    {
        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.
            // If we are still getting failures after three minutes, then we log them.
            if ((mDNSu32)mDNSPlatformRawTime() > (mDNSu32)(mDNSPlatformOneSecond * 180))
                LogMsg("mDNSPlatformSetDNSConfig: Error: dns_configuration_copy returned NULL");
        }
        else
        {
            LogInfo("mDNSPlatformSetDNSConfig: config->n_resolver = %d", config->n_resolver);

#if APPLE_OSX_mDNSResponder
            // Record the so-called "primary" domain, which we use as a hint to tell if the user is on a network set up
            // by someone using Microsoft Active Directory using "local" as a private internal top-level domain
            if (config->n_resolver && config->resolver[0]->domain && config->resolver[0]->n_nameserver && config->resolver[0]->nameserver[0])
                MakeDomainNameFromDNSNameString(&ActiveDirectoryPrimaryDomain, config->resolver[0]->domain);
            else ActiveDirectoryPrimaryDomain.c[0] = 0;
            //MakeDomainNameFromDNSNameString(&ActiveDirectoryPrimaryDomain, "test.local");
            ActiveDirectoryPrimaryDomainLabelCount = CountLabels(&ActiveDirectoryPrimaryDomain);
            if (config->n_resolver && config->resolver[0]->n_nameserver && SameDomainName(SkipLeadingLabels(&ActiveDirectoryPrimaryDomain, ActiveDirectoryPrimaryDomainLabelCount - 1), &localdomain))
                SetupAddr(&ActiveDirectoryPrimaryDomainServer, config->resolver[0]->nameserver[0]);
            else
            {
                AssignDomainName(&ActiveDirectoryPrimaryDomain, (const domainname *)"");
                ActiveDirectoryPrimaryDomainLabelCount = 0;
                ActiveDirectoryPrimaryDomainServer = zeroAddr;
            }
#endif

            // With scoped DNS, we don't want to answer a non-scoped question using a scoped cache entry
            // and vice-versa. As we compare resolverGroupID for matching cache entry with question, we need
            // to make sure that they don't match. We ensure this by always bumping up resolverGroupID between
            // the two calls to ConfigResolvers DNSServers for scoped and non-scoped can never have the
            // same resolverGroupID.
            //
            // All non-scoped resolvers use the same resolverGroupID i.e, we treat them all equally.
            ConfigResolvers(m, config, mDNSfalse, setsearch, setservers, &sdc, ++resolverGroupID);
            resolverGroupID += config->n_resolver;
#if DNSINFO_VERSION >= 20091104
            ConfigResolvers(m, config, mDNStrue, setsearch, setservers, &sdc, resolverGroupID);
#endif
            // Acking provides a hint that we processed this current configuration and
            // we will use that from now on, assuming we don't get another one immediately
            // after we return from here.
            _dns_configuration_ack(config, "com.apple.mDNSResponder");
            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

    SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:mDNSPlatformSetDNSConfig"), NULL, NULL);
    if (!store)
        LogMsg("mDNSPlatformSetDNSConfig: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
    else
    {
        CFDictionaryRef ddnsdict = SCDynamicStoreCopyValue(store, NetworkChangedKey_DynamicDNS);
        if (ddnsdict)
        {
            if (fqdn)
            {
                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))
                    {
                        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 (RegDomains)
            {
                CFArrayRef regArray = CFDictionaryGetValue(ddnsdict, CFSTR("RegistrationDomains"));
                if (regArray && CFArrayGetCount(regArray) > 0)
                {
                    CFDictionaryRef regDict = CFArrayGetValueAtIndex(regArray, 0);
                    if (regDict && DictionaryIsEnabled(regDict))
                    {
                        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
                            {
                                debugf("GetUserSpecifiedDDNSConfig SCDynamicStore DDNS registration domain: %s", buf);
                                AppendDNameListElem(&RegDomains, 0, &d);
                            }
                        }
                    }
                }
            }

            if (BrowseDomains)
            {
                CFArrayRef browseArray = CFDictionaryGetValue(ddnsdict, CFSTR("BrowseDomains"));
                if (browseArray)
                {
                    for (i = 0; i < CFArrayGetCount(browseArray); i++)
                    {
                        CFDictionaryRef browseDict = CFArrayGetValueAtIndex(browseArray, i);
                        if (browseDict && DictionaryIsEnabled(browseDict))
                        {
                            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
                                {
                                    debugf("GetUserSpecifiedDDNSConfig SCDynamicStore DDNS browsing domain: %s", buf);
                                    AppendDNameListElem(&BrowseDomains, 0, &d);
                                }
                            }
                        }
                    }
                }
            }
            CFRelease(ddnsdict);
        }

        if (RegDomains)
        {
            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++)
                {
                    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])
                        {
                            LogInfo("BackToMyMac %d %d %##s", i, uid, d.c);
                            AppendDNameListElem(&RegDomains, uid, &d);
                        }
                    }
                }
                CFRelease(btmm);
            }
        }

        if (setservers || setsearch)
        {
            CFDictionaryRef dict = SCDynamicStoreCopyValue(store, NetworkChangedKey_DNS);
            if (dict)
            {
                if (setservers)
                {
                    CFArrayRef values = CFDictionaryGetValue(dict, kSCPropNetDNSServerAddresses);
                    if (values)
                    {
                        LogInfo("DNS Server Address values: %d", (int)CFArrayGetCount(values));
                        for (i = 0; i < CFArrayGetCount(values); i++)
                        {
                            CFStringRef s = CFArrayGetValueAtIndex(values, i);
                            mDNSAddr addr = { mDNSAddrType_IPv4, { { { 0 } } } };
                            if (s && CFStringGetCString(s, buf, 256, kCFStringEncodingUTF8) &&
                                inet_aton(buf, (struct in_addr *) &addr.ip.v4))
                            {
                                LogInfo("Adding DNS server from dict: %s", buf);
                                mDNS_AddDNSServer(m, mDNSNULL, mDNSInterface_Any, &addr, UnicastDNSPort, mDNSfalse, 0, mDNSfalse, 0);
                            }
                        }
                    }
                    else LogInfo("No DNS Server Address values");
                }
                if (setsearch)
                {
                    // Add the manual and/or DHCP-dicovered search domains
                    CFArrayRef searchDomains = CFDictionaryGetValue(dict, kSCPropNetDNSSearchDomains);
                    if (searchDomains)
                    {
                        for (i = 0; i < CFArrayGetCount(searchDomains); i++)
                        {
                            CFStringRef s = CFArrayGetValueAtIndex(searchDomains, i);
                            if (s && CFStringGetCString(s, buf, sizeof(buf), kCFStringEncodingUTF8))
                            {
                                UpdateSearchDomainHash(m, &sdc, buf, NULL);
                                mDNS_AddSearchDomain_CString(buf, mDNSNULL);
                            }
                        }
                    }
                    else    // No kSCPropNetDNSSearchDomains, so use kSCPropNetDNSDomainName
                    {
                        // Due to the vagaries of Apple's SystemConfiguration and dnsinfo.h APIs, if there are no search domains
                        // listed, then you're supposed to interpret the "domain" field as also being the search domain, but if
                        // there *are* search domains listed, then you're supposed to ignore the "domain" field completely and
                        // instead use the search domain list as the sole authority for what domains to search and in what order
                        // (and the domain from the "domain" field will also appear somewhere in that list).
                        CFStringRef string = CFDictionaryGetValue(dict, kSCPropNetDNSDomainName);
                        if (string && CFStringGetCString(string, buf, sizeof(buf), kCFStringEncodingUTF8))
                        {
                            UpdateSearchDomainHash(m, &sdc, buf, NULL);
                            mDNS_AddSearchDomain_CString(buf, mDNSNULL);
                        }
                    }
                    FinalizeSearchDomainHash(m, &sdc);
                }
                CFRelease(dict);
            }
        }
        CFRelease(store);
    }
}

mDNSexport mStatus mDNSPlatformGetPrimaryInterface(mDNS *const m, mDNSAddr *v4, mDNSAddr *v6, mDNSAddr *r)
{
    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(store, NetworkChangedKey_IPv4);
        if (dict)
        {
            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
                {
                    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;

                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))
                    {
                        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; }
                        }
                    }
                    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);
    }
    return mStatus_NoError;
}

mDNSexport void mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status)
{
    LogInfo("mDNSPlatformDynDNSHostNameStatusChanged %d %##s", status, dname->c);
    char uname[MAX_ESCAPED_DOMAIN_NAME];    // Max legal C-string name, including terminating NUL
    ConvertDomainNameToCString(dname, uname);

    char *p = uname;
    while (*p)
    {
        *p = tolower(*p);
        if (!(*(p+1)) && *p == '.') *p = 0; // if last character, strip trailing dot
        p++;
    }

    // We need to make a CFDictionary called "State:/Network/DynamicDNS" containing (at present) a single entity.
    // That single entity is a CFDictionary with name "HostNames".
    // The "HostNames" CFDictionary contains a set of name/value pairs, where the each name is the FQDN
    // in question, and the corresponding value is a CFDictionary giving the state for that FQDN.
    // (At present we only support a single FQDN, so this dictionary holds just a single name/value pair.)
    // The CFDictionary for each FQDN holds (at present) a single name/value pair,
    // where the name is "Status" and the value is a CFNumber giving an errror code (with zero meaning success).

    const CFStringRef StateKeys [1] = { CFSTR("HostNames") };
    const CFStringRef HostKeys  [1] = { CFStringCreateWithCString(NULL, uname, kCFStringEncodingUTF8) };
    const CFStringRef StatusKeys[1] = { CFSTR("Status") };
    if (!HostKeys[0]) LogMsg("SetDDNSNameStatus: CFStringCreateWithCString(%s) failed", uname);
    else
    {
        const CFNumberRef StatusVals[1] = { CFNumberCreate(NULL, kCFNumberSInt32Type, &status) };
        if (!StatusVals[0]) LogMsg("SetDDNSNameStatus: CFNumberCreate(%d) failed", status);
        else
        {
            const CFDictionaryRef HostVals[1] = { CFDictionaryCreate(NULL, (void*)StatusKeys, (void*)StatusVals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks) };
            if (HostVals[0])
            {
                const CFDictionaryRef StateVals[1] = { CFDictionaryCreate(NULL, (void*)HostKeys, (void*)HostVals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks) };
                if (StateVals[0])
                {
                    CFDictionaryRef StateDict = CFDictionaryCreate(NULL, (void*)StateKeys, (void*)StateVals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
                    if (StateDict)
                    {
                        mDNSDynamicStoreSetConfig(kmDNSDynamicConfig, mDNSNULL, StateDict);
                        CFRelease(StateDict);
                    }
                    CFRelease(StateVals[0]);
                }
                CFRelease(HostVals[0]);
            }
            CFRelease(StatusVals[0]);
        }
        CFRelease(HostKeys[0]);
    }
}

#if APPLE_OSX_mDNSResponder
#if !NO_AWACS

// checks whether a domain is present in Setup:/Network/BackToMyMac. Just because there is a key in the
// keychain for a domain, it does not become a valid BTMM domain. If things get inconsistent, this will
// help catch it
mDNSlocal mDNSBool IsBTMMDomain(domainname *d)
{
    SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:IsBTMMDomain"), NULL, NULL);
    if (!store)
    {
        LogMsg("IsBTMMDomain: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
        return mDNSfalse;
    }
    CFDictionaryRef btmm = SCDynamicStoreCopyValue(store, NetworkChangedKey_BackToMyMac);
    if (btmm)
    {
        CFIndex size = CFDictionaryGetCount(btmm);
        char buf[MAX_ESCAPED_DOMAIN_NAME];  // Max legal C-string name, including terminating NUL
        const void *key[size];
        const void *val[size];
        domainname dom;
        int i;
        CFDictionaryGetKeysAndValues(btmm, key, val);
        for (i = 0; i < size; i++)
        {
            LogInfo("BackToMyMac %d", i);
            if (!CFStringGetCString(key[i], buf, sizeof(buf), kCFStringEncodingUTF8))
                LogMsg("IsBTMMDomain: ERROR!! Can't read BackToMyMac %d key %s", i, buf);
            else
            {
                mDNSu32 uid = atoi(buf);
                if (!CFStringGetCString(val[i], buf, sizeof(buf), kCFStringEncodingUTF8))
                    LogMsg("IsBTMMDomain: Can't read BackToMyMac %d val %s", i, buf);
                else if (MakeDomainNameFromDNSNameString(&dom, buf) && dom.c[0])
                {
                    if (SameDomainName(&dom, d))
                    {
                        LogInfo("IsBTMMDomain: Domain %##s is a btmm domain, uid %u", d->c, uid);
                        CFRelease(btmm);
                        CFRelease(store);
                        return mDNStrue;
                    }
                }
            }
        }
        CFRelease(btmm);
    }
    CFRelease(store);
    LogInfo("IsBTMMDomain: Domain %##s not a btmm domain", d->c);
    return mDNSfalse;
}

// Appends data to the buffer
mDNSlocal int AddOneItem(char *buf, int bufsz, char *data, int *currlen)
{
    int len;

    len = strlcpy(buf + *currlen, data, bufsz - *currlen);
    if (len >= (bufsz - *currlen))
    {
        // if we have exceeded the space in buf, it has already been NULL terminated
        // and we have nothing more to do. Set currlen to the last byte so that the caller
        // knows to do the right thing
        LogMsg("AddOneItem: Exceeded the max buffer size currlen %d, len %d", *currlen, len);
        *currlen = bufsz - 1;
        return -1;
    }
    else { (*currlen) += len; }

    buf[*currlen] = ',';
    if (*currlen >= bufsz)
    {
        LogMsg("AddOneItem: ERROR!! How can currlen be %d", *currlen);
        *currlen = bufsz - 1;
        buf[*currlen] = 0;
        return -1;
    }
    // if we have filled up the buffer exactly, then there is no more work to do
    if (*currlen == bufsz - 1) { buf[*currlen] = 0; return -1; }
    (*currlen)++;
    return *currlen;
}

// If we have at least one BTMM domain, then trigger the connection to the relay. If we have no
// BTMM domains, then bring down the connection to the relay.
mDNSlocal void UpdateBTMMRelayConnection(mDNS *const m)
{
    DomainAuthInfo *BTMMDomain = mDNSNULL;
    DomainAuthInfo *FoundInList;
    static mDNSBool AWACSDConnected = mDNSfalse;
    char AllUsers[1024];    // maximum size of mach message
    char AllPass[1024];     // maximum size of mach message
    char username[MAX_DOMAIN_LABEL + 1];
    int currulen = 0;
    int currplen = 0;

    // if a domain is being deleted, we want to send a disconnect. If we send a disconnect now,
    // we may not be able to send the dns queries over the relay connection which may be needed
    // for sending the deregistrations. Hence, we need to delay sending the disconnect. But we
    // need to make sure that we send the disconnect before attempting the next connect as the
    // awacs connections are redirected based on usernames.
    //
    // For now we send a disconnect immediately. When we start sending dns queries over the relay
    // connection, we will need to fix this.

    for (FoundInList = m->AuthInfoList; FoundInList; FoundInList = FoundInList->next)
        if (!FoundInList->deltime && FoundInList->AutoTunnel && IsBTMMDomain(&FoundInList->domain))
        {
            // We need the passwd from the first domain.
            BTMMDomain = FoundInList;
            ConvertDomainLabelToCString_unescaped((domainlabel *)BTMMDomain->domain.c, username);
            LogInfo("UpdateBTMMRelayConnection: user %s for domain %##s", username, BTMMDomain->domain.c);
            if (AddOneItem(AllUsers, sizeof(AllUsers), username, &currulen) == -1) break;
            if (AddOneItem(AllPass, sizeof(AllPass), BTMMDomain->b64keydata, &currplen) == -1) break;
        }

    if (BTMMDomain)
    {
        // In the normal case (where we neither exceed the buffer size nor write bytes that
        // fit exactly into the buffer), currulen/currplen should be a different size than
        // (AllUsers - 1) / (AllPass - 1). In that case, we need to override the "," with a NULL byte.

        if (currulen != (int)(sizeof(AllUsers) - 1)) AllUsers[currulen - 1] = 0;
        if (currplen != (int)(sizeof(AllPass) - 1)) AllPass[currplen - 1] = 0;

        LogInfo("UpdateBTMMRelayConnection: AWS_Connect for user %s", AllUsers);
        AWACS_Connect(AllUsers, AllPass, "hello.connectivity.me.com");
        AWACSDConnected = mDNStrue;
    }
    else
    {
        // Disconnect only if we connected previously
        if (AWACSDConnected)
        {
            LogInfo("UpdateBTMMRelayConnection: AWS_Disconnect");
            AWACS_Disconnect();
            AWACSDConnected = mDNSfalse;
        }
        else LogInfo("UpdateBTMMRelayConnection: Not calling AWS_Disconnect");
    }
}
#else
mDNSlocal void UpdateBTMMRelayConnection(mDNS *const m)
{
    (void) m; // Unused
    LogInfo("UpdateBTMMRelayConnection: AWACS connection not started, no AWACS library");
}
#endif // ! NO_AWACS

mDNSlocal void ProcessConndConfigChanges(mDNS *const m);

#endif // APPLE_OSX_mDNSResponder

// MUST be called holding the lock
mDNSexport void SetDomainSecrets(mDNS *m)
{
#ifdef NO_SECURITYFRAMEWORK
        (void) m;
    LogMsg("Note: SetDomainSecrets: no keychain support");
#else
    mDNSBool haveAutoTunnels = mDNSfalse;

    LogInfo("SetDomainSecrets");

    // Rather than immediately deleting all keys now, we mark them for deletion in ten seconds.
    // In the case where the user simultaneously removes their DDNS host name and the key
    // for it, this gives mDNSResponder ten seconds to gracefully delete the name from the
    // server before it loses access to the necessary key. Otherwise, we'd leave orphaned
    // address records behind that we no longer have permission to delete.
    DomainAuthInfo *ptr;
    for (ptr = m->AuthInfoList; ptr; ptr = ptr->next)
        ptr->deltime = NonZeroTime(m->timenow + mDNSPlatformOneSecond*10);

#if APPLE_OSX_mDNSResponder
    {
        // Mark all TunnelClients for deletion
        ClientTunnel *client;
        for (client = m->TunnelClients; client; client = client->next)
        {
            LogInfo("SetDomainSecrets: tunnel to %##s marked for deletion", client->dstname.c);
            client->MarkedForDeletion = mDNStrue;
        }
    }
#endif // APPLE_OSX_mDNSResponder

    // String Array used to write list of private domains to Dynamic Store
    CFMutableArrayRef sa = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
    if (!sa) { LogMsg("SetDomainSecrets: CFArrayCreateMutable failed"); return; }
    CFIndex i;
    CFDataRef data = NULL;
    const int itemsPerEntry = 4; // domain name, key name, key value, Name value
    CFArrayRef secrets = NULL;
    int err = mDNSKeychainGetSecrets(&secrets);
    if (err || !secrets)
        LogMsg("SetDomainSecrets: mDNSKeychainGetSecrets failed error %d CFArrayRef %p", err, secrets);
    else
    {
        CFIndex ArrayCount = CFArrayGetCount(secrets);
        // Iterate through the secrets
        for (i = 0; i < ArrayCount; ++i)
        {
            mDNSBool AutoTunnel;
            int j, offset;
            CFArrayRef entry = CFArrayGetValueAtIndex(secrets, i);
            if (CFArrayGetTypeID() != CFGetTypeID(entry) || itemsPerEntry != CFArrayGetCount(entry))
            { LogMsg("SetDomainSecrets: malformed entry %d, itemsPerEntry %d", i, itemsPerEntry); continue; }
            for (j = 0; j < CFArrayGetCount(entry); ++j)
                if (CFDataGetTypeID() != CFGetTypeID(CFArrayGetValueAtIndex(entry, j)))
                { LogMsg("SetDomainSecrets: malformed entry item %d", j); continue; }

            // The names have already been vetted by the helper, but checking them again here helps humans and automated tools verify correctness

            // Max legal domainname as C-string, including space for btmmprefix and terminating NUL
            // Get DNS domain this key is for (kmDNSKcWhere)
            char stringbuf[MAX_ESCAPED_DOMAIN_NAME + sizeof(btmmprefix)];
            data = CFArrayGetValueAtIndex(entry, kmDNSKcWhere);
            if (CFDataGetLength(data) >= (int)sizeof(stringbuf))
            { LogMsg("SetDomainSecrets: Bad kSecServiceItemAttr length %d", CFDataGetLength(data)); continue; }
            CFDataGetBytes(data, CFRangeMake(0, CFDataGetLength(data)), (UInt8 *)stringbuf);
            stringbuf[CFDataGetLength(data)] = '\0';

            AutoTunnel = mDNSfalse;
            offset = 0;
            if (!strncmp(stringbuf, dnsprefix, strlen(dnsprefix)))
                offset = strlen(dnsprefix);
            else if (!strncmp(stringbuf, btmmprefix, strlen(btmmprefix)))
            {
                AutoTunnel = mDNStrue;
                offset = strlen(btmmprefix);
            }
            domainname domain;
            if (!MakeDomainNameFromDNSNameString(&domain, stringbuf + offset)) { LogMsg("SetDomainSecrets: bad key domain %s", stringbuf); continue; }

            // Get key name (kmDNSKcAccount)
            data = CFArrayGetValueAtIndex(entry, kmDNSKcAccount);
            if (CFDataGetLength(data) >= (int)sizeof(stringbuf))
            { LogMsg("SetDomainSecrets: Bad kSecAccountItemAttr length %d", CFDataGetLength(data)); continue; }
            CFDataGetBytes(data, CFRangeMake(0,CFDataGetLength(data)), (UInt8 *)stringbuf);
            stringbuf[CFDataGetLength(data)] = '\0';

            domainname keyname;
            if (!MakeDomainNameFromDNSNameString(&keyname, stringbuf)) { LogMsg("SetDomainSecrets: bad key name %s", stringbuf); continue; }

            // Get key data (kmDNSKcKey)
            data = CFArrayGetValueAtIndex(entry, kmDNSKcKey);
            if (CFDataGetLength(data) >= (int)sizeof(stringbuf))
            { 
                LogMsg("SetDomainSecrets: Shared secret too long: %d", CFDataGetLength(data));
                continue;
            }
            CFDataGetBytes(data, CFRangeMake(0, CFDataGetLength(data)), (UInt8 *)stringbuf);
            stringbuf[CFDataGetLength(data)] = '\0';    // mDNS_SetSecretForDomain requires NULL-terminated C string for key

            // Get the Name of the keychain entry (kmDNSKcName) host or host:port
            // The hostname also has the port number and ":". It should take a maximum of 6 bytes.
            char hostbuf[MAX_ESCAPED_DOMAIN_NAME + 6];  // Max legal domainname as C-string, including terminating NUL
            data = CFArrayGetValueAtIndex(entry, kmDNSKcName);
            if (CFDataGetLength(data) >= (int)sizeof(hostbuf))
            { 
                LogMsg("SetDomainSecrets: host:port data too long: %d", CFDataGetLength(data));
                continue;
            }
            CFDataGetBytes(data, CFRangeMake(0,CFDataGetLength(data)), (UInt8 *)hostbuf);
            hostbuf[CFDataGetLength(data)] = '\0';

            domainname hostname;
            mDNSIPPort port;
            char *hptr;
            hptr = strchr(hostbuf, ':');

            port.NotAnInteger = 0;
            if (hptr)
            {
                mDNSu8 *p;
                mDNSu16 val = 0;

                *hptr++ = '\0';
                while(hptr && *hptr != 0)
                {
                    if (*hptr < '0' || *hptr > '9')
                    { LogMsg("SetDomainSecrets: Malformed Port number %d, val %d", *hptr, val); val = 0; break;}
                    val = val * 10 + *hptr - '0';
                    hptr++;
                }
                if (!val) continue;
                p = (mDNSu8 *)&val;
                port.NotAnInteger = p[0] << 8 | p[1];
            }
            // The hostbuf is of the format dsid@hostname:port. We don't care about the dsid.
            hptr = strchr(hostbuf, '@');
            if (hptr)
                hptr++;
            else
                hptr = hostbuf;
            if (!MakeDomainNameFromDNSNameString(&hostname, hptr)) { LogMsg("SetDomainSecrets: bad host name %s", hptr); continue; }

            DomainAuthInfo *FoundInList;
            for (FoundInList = m->AuthInfoList; FoundInList; FoundInList = FoundInList->next)
                if (SameDomainName(&FoundInList->domain, &domain)) break;

#if APPLE_OSX_mDNSResponder
            if (FoundInList)
            {
                // If any client tunnel destination is in this domain, set deletion flag to false
                ClientTunnel *client;
                for (client = m->TunnelClients; client; client = client->next)
                    if (FoundInList == GetAuthInfoForName_internal(m, &client->dstname))
                    {
                        LogInfo("SetDomainSecrets: tunnel to %##s no longer marked for deletion", client->dstname.c);
                        client->MarkedForDeletion = mDNSfalse;
                    }
            }

#endif // APPLE_OSX_mDNSResponder

            // Uncomment the line below to view the keys as they're read out of the system keychain
            // DO NOT SHIP CODE THIS WAY OR YOU'LL LEAK SECRET DATA INTO A PUBLICLY READABLE FILE!
            //LogInfo("SetDomainSecrets: domain %##s keyname %##s key %s hostname %##s port %d", &domain.c, &keyname.c, stringbuf, hostname.c, (port.b[0] << 8 | port.b[1]));
            LogInfo("SetDomainSecrets: domain %##s keyname %##s hostname %##s port %d", &domain.c, &keyname.c, hostname.c, (port.b[0] << 8 | port.b[1]));

            // If didn't find desired domain in the list, make a new entry
            ptr = FoundInList;
            if (FoundInList && FoundInList->AutoTunnel && haveAutoTunnels == mDNSfalse) haveAutoTunnels = mDNStrue;
            if (!FoundInList)
            {
                ptr = (DomainAuthInfo*)mallocL("DomainAuthInfo", sizeof(*ptr));
                if (!ptr) { LogMsg("SetDomainSecrets: No memory"); continue; }
            }

            //LogInfo("SetDomainSecrets: %d of %d %##s", i, ArrayCount, &domain);

            // It is an AutoTunnel if the keychains tells us so (with btmm prefix) or if it is a TunnelModeDomain
            if (mDNS_SetSecretForDomain(m, ptr, &domain, &keyname, stringbuf, &hostname, &port, AutoTunnel) == mStatus_BadParamErr)
            {
                if (!FoundInList) mDNSPlatformMemFree(ptr);     // If we made a new DomainAuthInfo here, and it turned out bad, dispose it immediately
                continue;
            }

            ConvertDomainNameToCString(&domain, stringbuf);
            CFStringRef cfs = CFStringCreateWithCString(NULL, stringbuf, kCFStringEncodingUTF8);
            if (cfs) { CFArrayAppendValue(sa, cfs); CFRelease(cfs); }
        }
        CFRelease(secrets);
    }
    mDNSDynamicStoreSetConfig(kmDNSPrivateConfig, mDNSNULL, sa);
    CFRelease(sa);

#if APPLE_OSX_mDNSResponder
    {
        // clean up ClientTunnels
        ClientTunnel **pp = &m->TunnelClients;
        while (*pp)
        {
            if ((*pp)->MarkedForDeletion)
            {
                ClientTunnel *cur = *pp;
                LogInfo("SetDomainSecrets: removing client %p %##s from list", cur, cur->dstname.c);
                if (cur->q.ThisQInterval >= 0) mDNS_StopQuery(m, &cur->q);
                AutoTunnelSetKeys(cur, mDNSfalse);
                *pp = cur->next;
                freeL("ClientTunnel", cur);
            }
            else
                pp = &(*pp)->next;
        }

        mDNSBool needAutoTunnelNAT = mDNSfalse;
        DomainAuthInfo *info;
        for (info = m->AuthInfoList; info; info = info->next)
        {
            if (info->AutoTunnel)
            {
                UpdateAutoTunnelDeviceInfoRecord(m, info);
                UpdateAutoTunnelHostRecord(m, info);
                UpdateAutoTunnelServiceRecords(m, info);
                UpdateAutoTunnel6Record(m, info);
                if (info->deltime)
                {
                    if (info->AutoTunnelServiceStarted) info->AutoTunnelServiceStarted = mDNSfalse;
                }
                else if (info->AutoTunnelServiceStarted)
                    needAutoTunnelNAT = true;

	            UpdateAutoTunnelDomainStatus(m, info);
            }
        }

        // If the AutoTunnel NAT-T is no longer needed (& is currently running), stop it
        if (!needAutoTunnelNAT && m->AutoTunnelNAT.clientContext)
        {
            // stop the NAT operation, reset port, cleanup state
            mDNS_StopNATOperation_internal(m, &m->AutoTunnelNAT);
            m->AutoTunnelNAT.ExternalAddress = m->ExternalAddress;
            m->AutoTunnelNAT.ExternalPort    = zeroIPPort;
            m->AutoTunnelNAT.RequestedPort   = zeroIPPort;
            m->AutoTunnelNAT.Lifetime        = 0;
            m->AutoTunnelNAT.Result          = mStatus_NoError;
            m->AutoTunnelNAT.clientContext   = mDNSNULL;
        }

        UpdateAnonymousRacoonConfig(m);     // Determine whether we need racoon to accept incoming connections
        ProcessConndConfigChanges(m);       // Update AutoTunnelInnerAddress values and default ipsec policies as necessary
    }
#endif // APPLE_OSX_mDNSResponder

    CheckSuppressUnusableQuestions(m);

#endif /* NO_SECURITYFRAMEWORK */
}

mDNSlocal void SetLocalDomains(void)
{
    CFMutableArrayRef sa = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
    if (!sa) { LogMsg("SetLocalDomains: CFArrayCreateMutable failed"); return; }

    CFArrayAppendValue(sa, CFSTR("local"));
    CFArrayAppendValue(sa, CFSTR("254.169.in-addr.arpa"));
    CFArrayAppendValue(sa, CFSTR("8.e.f.ip6.arpa"));
    CFArrayAppendValue(sa, CFSTR("9.e.f.ip6.arpa"));
    CFArrayAppendValue(sa, CFSTR("a.e.f.ip6.arpa"));
    CFArrayAppendValue(sa, CFSTR("b.e.f.ip6.arpa"));

    mDNSDynamicStoreSetConfig(kmDNSMulticastConfig, mDNSNULL, sa);
    CFRelease(sa);
}

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)
    {
        char buf[256];
        if (!CFStringGetCString(str, buf, sizeof(buf), kCFStringEncodingUTF8)) buf[0] = 0;
        LogMsg("GetCurrentPMSetting: CFDictionaryGetValue (%s) failed!", buf);
        goto end;
    }

    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);
    }

#endif
}

#if APPLE_OSX_mDNSResponder

static CFMutableDictionaryRef spsStatusDict = NULL;
static const CFStringRef kMetricRef = CFSTR("Metric");

mDNSlocal void SPSStatusPutNumber(CFMutableDictionaryRef dict, const mDNSu8* const ptr, CFStringRef key)
{
    mDNSu8 tmp = (ptr[0] - '0') * 10 + ptr[1] - '0';
    CFNumberRef num = CFNumberCreate(NULL, kCFNumberSInt8Type, &tmp);
    if (!num)
        LogMsg("SPSStatusPutNumber: Could not create CFNumber");
    else
    {
        CFDictionarySetValue(dict, key, num);
        CFRelease(num);
    }
}

mDNSlocal CFMutableDictionaryRef SPSCreateDict(const mDNSu8* const ptr)
{
    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    if (!dict) { LogMsg("SPSCreateDict: Could not create CFDictionary dict"); return dict; }

    char buffer[1024];
    buffer[mDNS_snprintf(buffer, sizeof(buffer), "%##s", ptr) - 1] = 0;
    CFStringRef spsname = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
    if (!spsname) { LogMsg("SPSCreateDict: Could not create CFString spsname full"); CFRelease(dict); return NULL; }
    CFDictionarySetValue(dict, CFSTR("FullName"), spsname);
    CFRelease(spsname);

    if (ptr[0] >=  2) SPSStatusPutNumber(dict, ptr + 1, CFSTR("Type"));
    if (ptr[0] >=  5) SPSStatusPutNumber(dict, ptr + 4, CFSTR("Portability"));
    if (ptr[0] >=  8) SPSStatusPutNumber(dict, ptr + 7, CFSTR("MarginalPower"));
    if (ptr[0] >= 11) SPSStatusPutNumber(dict, ptr +10, CFSTR("TotalPower"));

    mDNSu32 tmp = SPSMetric(ptr);
    CFNumberRef num = CFNumberCreate(NULL, kCFNumberSInt32Type, &tmp);
    if (!num)
        LogMsg("SPSCreateDict: Could not create CFNumber");
    else
    {
        CFDictionarySetValue(dict, kMetricRef, num);
        CFRelease(num);
    }

    if (ptr[0] >= 12)
    {
        memcpy(buffer, ptr + 13, ptr[0] - 12);
        buffer[ptr[0] - 12] = 0;
        spsname = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
        if (!spsname) { LogMsg("SPSCreateDict: Could not create CFString spsname"); CFRelease(dict); return NULL; }
        else
        {
            CFDictionarySetValue(dict, CFSTR("PrettyName"), spsname);
            CFRelease(spsname);
        }
    }

    return dict;
}

mDNSlocal CFComparisonResult CompareSPSEntries(const void *val1, const void *val2, void *context)
{
    (void)context;
    return CFNumberCompare((CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)val1, kMetricRef),
                           (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)val2, kMetricRef),
                           NULL);
}

mDNSlocal void UpdateSPSStatus(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
    NetworkInterfaceInfo* info = (NetworkInterfaceInfo*)question->QuestionContext;
    debugf("UpdateSPSStatus: %s %##s %s %s", info->ifname, question->qname.c, AddRecord ? "Add" : "Rmv", answer ? RRDisplayString(m, answer) : "<null>");

    mDNS_Lock(m);
    mDNS_UpdateAllowSleep(m);
    mDNS_Unlock(m);

    if (answer && SPSMetric(answer->rdata->u.name.c) > 999999) return;  // Ignore instances with invalid names

    if (!spsStatusDict)
    {
        spsStatusDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        if (!spsStatusDict) { LogMsg("UpdateSPSStatus: Could not create CFDictionary spsStatusDict"); return; }
    }

    CFStringRef ifname = CFStringCreateWithCString(NULL, info->ifname, kCFStringEncodingUTF8);
    if (!ifname) { LogMsg("UpdateSPSStatus: Could not create CFString ifname"); return; }

    CFMutableArrayRef array = NULL;

    if (!CFDictionaryGetValueIfPresent(spsStatusDict, ifname, (const void**) &array))
    {
        array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        if (!array) { LogMsg("UpdateSPSStatus: Could not create CFMutableArray"); CFRelease(ifname); return; }
        CFDictionarySetValue(spsStatusDict, ifname, array);
        CFRelease(array); // let go of our reference, now that the dict has one
    }
    else
    if (!array) { LogMsg("UpdateSPSStatus: Could not get CFMutableArray for %s", info->ifname); CFRelease(ifname); return; }

    if (!answer) // special call that means the question has been stopped (because the interface is going away)
        CFArrayRemoveAllValues(array);
    else
    {
        CFMutableDictionaryRef dict = SPSCreateDict(answer->rdata->u.name.c);
        if (!dict) { CFRelease(ifname); return; }

        if (AddRecord)
        {
            if (!CFArrayContainsValue(array, CFRangeMake(0, CFArrayGetCount(array)), dict))
            {
                int i=0;
                for (i=0; i<CFArrayGetCount(array); i++)
                    if (CompareSPSEntries(CFArrayGetValueAtIndex(array, i), dict, NULL) != kCFCompareLessThan)
                        break;
                CFArrayInsertValueAtIndex(array, i, dict);
            }
            else LogMsg("UpdateSPSStatus: %s array already contains %##s", info->ifname, answer->rdata->u.name.c);
        }
        else
        {
            CFIndex i = CFArrayGetFirstIndexOfValue(array, CFRangeMake(0, CFArrayGetCount(array)), dict);
            if (i != -1) CFArrayRemoveValueAtIndex(array, i);
            else LogMsg("UpdateSPSStatus: %s array does not contain %##s", info->ifname, answer->rdata->u.name.c);
        }

        CFRelease(dict);
    }

    if (!m->ShutdownTime) mDNSDynamicStoreSetConfig(kmDNSSleepProxyServersState, info->ifname, array);

    CFRelease(ifname);
}

mDNSlocal mDNSs32 GetSystemSleepTimerSetting(void)
{
    mDNSs32 val = -1;
    SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:GetSystemSleepTimerSetting"), NULL, NULL);
    if (!store)
        LogMsg("GetSystemSleepTimerSetting: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
    else
    {
        CFDictionaryRef dict = SCDynamicStoreCopyValue(store, NetworkChangedKey_PowerSettings);
        if (dict)
        {
            CFNumberRef number = CFDictionaryGetValue(dict, CFSTR("System Sleep Timer"));
            if (number) CFNumberGetValue(number, kCFNumberSInt32Type, &val);
            CFRelease(dict);
        }
        CFRelease(store);
    }
    return val;
}

#if !TARGET_OS_IPHONE
mDNSlocal mDNSBool GetInternetSharingStatus(void)
{
    mDNSBool ret = mDNSfalse;

	// Currently, we do not have a mechanism to advertise sleep proxy services only on the network on which Internet sharing
	// is enabled. As a result, we start acting as a very unreliable sleep proxy on other networks when Internet sharing is
	// turned on.
	// We should look at ways to advertise only on the relevant network. Till this is done, we should turn off this feature.
    LogInfo("GetInternetSharingStatus: Disabled");
    return mDNSfalse;

    SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:mDNSPlatformInternetSharing"), NULL, NULL);
    if (!store)
        LogMsg("GetInternetSharingStatus: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
    else
    {
        CFDictionaryRef dict = SCDynamicStoreCopyValue(store, NetworkChangedKey_InternetSharing);
        if (dict)
        {
            CFNumberRef state = (CFNumberRef)CFDictionaryGetValue(dict, CFSTR("State"));
            if (state)
            {
                mDNSu32 val;
                if (CFNumberGetValue(state, kCFNumberSInt32Type, &val))
                    ret = (val ==  MIS_SVC_STATE_ON) ? mDNStrue :  mDNSfalse;
                else
                    LogMsg("GetInternetSharingStatus: CFNumberGetValue error");
            }
            CFRelease(dict);
        }
        CFRelease(store);
    }
    LogInfo("GetInternetSharingStatus: Internet Sharing state %s", (!ret ? "OFF" : "ON"));
    return ret;
}
#else
// We don't want to support this yet in embedded
mDNSlocal mDNSBool GetInternetSharingStatus(void)
{
    LogInfo("GetInternetSharingStatus: Disabled on embedded");
    return mDNSfalse;
}
#endif

mDNSlocal void SetSPS(mDNS *const m)
{
    mDNSu8 sps = GetInternetSharingStatus() ? mDNSSleepProxyMetric_PrimarySoftware :
                 (OfferSleepProxyService && GetSystemSleepTimerSetting() == 0) ? mDNSSleepProxyMetric_IncidentalSoftware : 0;

    // For devices that are not running NAT, but are set to never sleep, we may choose to act
    // as a Sleep Proxy, but only for non-portable Macs (Portability > 35 means nominal weight < 3kg)
    //if (sps > mDNSSleepProxyMetric_PrimarySoftware && SPMetricPortability > 35) sps = 0;

    // If we decide to let laptops act as Sleep Proxy, we should do it only when running on AC power, not on battery

    // For devices that are unable to sleep at all to save power, or save 1W or less by sleeping,
    // it makes sense for them to offer low-priority Sleep Proxy service on the network.
    // We rate such a device as metric 70 ("Incidentally Available Hardware")
    if (SPMetricMarginalPower <= 60 && !sps) sps = mDNSSleepProxyMetric_IncidentalHardware;

    // If the launchd plist specifies an explicit value for the Intent Metric, then use that instead of the
    // computed value (currently 40 "Primary Network Infrastructure Software" or 80 "Incidentally Available Software")
    if (sps && OfferSleepProxyService && OfferSleepProxyService < 100) sps = OfferSleepProxyService;

    mDNSCoreBeSleepProxyServer(m, sps, SPMetricPortability, SPMetricMarginalPower, SPMetricTotalPower, SPMetricFeatures);
}

// The definitions below should eventually come from some externally-supplied header file.
// However, since these definitions can't really be changed without breaking binary compatibility,
// they should never change, so in practice it should not be a big problem to have them defined here.

#define mDNS_IOREG_KEY               "mDNS_KEY"
#define mDNS_IOREG_VALUE             "2009-07-30"
#define mDNS_USER_CLIENT_CREATE_TYPE 'mDNS'

enum
{                               // commands from the daemon to the driver
    cmd_mDNSOffloadRR = 21,     // give the mdns update buffer to the driver
};

typedef union { void *ptr; mDNSOpaque64 sixtyfourbits; } FatPtr;

typedef struct
{                                       // cmd_mDNSOffloadRR structure
    uint32_t command;                 // set to OffloadRR
    uint32_t rrBufferSize;            // number of bytes of RR records
    uint32_t numUDPPorts;             // number of SRV UDP ports
    uint32_t numTCPPorts;             // number of SRV TCP ports
    uint32_t numRRRecords;            // number of RR records
    uint32_t compression;             // rrRecords - compression is base for compressed strings
    FatPtr rrRecords;                 // address of array of pointers to the rr records
    FatPtr udpPorts;                  // address of udp port list (SRV)
    FatPtr tcpPorts;                  // address of tcp port list (SRV)
} mDNSOffloadCmd;

#include <IOKit/IOKitLib.h>
#include <dns_util.h>

mDNSlocal mDNSu16 GetPortArray(mDNS *const m, int trans, mDNSIPPort *portarray)
{
    const domainlabel *const tp = (trans == mDNSTransport_UDP) ? (const domainlabel *)"\x4_udp" : (const domainlabel *)"\x4_tcp";
    int count = 0;
    AuthRecord *rr;
    for (rr = m->ResourceRecords; rr; rr=rr->next)
        if (rr->resrec.rrtype == kDNSType_SRV && SameDomainLabel(ThirdLabel(rr->resrec.name)->c, tp->c))
        {
            if (portarray) portarray[count] = rr->resrec.rdata->u.srv.port;
            count++;
        }

    // If Back to My Mac is on, also wake for packets to the IPSEC UDP port (4500)
    if (trans == mDNSTransport_UDP && m->AutoTunnelNAT.clientContext)
    {
        LogSPS("GetPortArray Back to My Mac at %d", count);
        if (portarray) portarray[count] = IPSECPort;
        count++;
    }
    return(count);
}

#define TfrRecordToNIC(RR) \
    ((!(RR)->resrec.InterfaceID && ((RR)->ForceMCast || IsLocalDomain((RR)->resrec.name))))

mDNSlocal mDNSu32 CountProxyRecords(mDNS *const m, uint32_t *const numbytes)
{
    *numbytes = 0;
    int count = 0;
    AuthRecord *rr;
    for (rr = m->ResourceRecords; rr; rr=rr->next)
        if (rr->resrec.RecordType > kDNSRecordTypeDeregistering)
            if (TfrRecordToNIC(rr))
            {
                *numbytes += DomainNameLength(rr->resrec.name) + 10 + rr->resrec.rdestimate;
                LogSPS("CountProxyRecords: %3d size %5d total %5d %s",
                       count, DomainNameLength(rr->resrec.name) + 10 + rr->resrec.rdestimate, *numbytes, ARDisplayString(m,rr));
                count++;
            }
    return(count);
}

mDNSlocal void GetProxyRecords(mDNS *const m, DNSMessage *const msg, uint32_t *const numbytes, FatPtr *const records)
{
    mDNSu8 *p = msg->data;
    const mDNSu8 *const limit = p + *numbytes;
    InitializeDNSMessage(&msg->h, zeroID, zeroID);

    int count = 0;
    AuthRecord *rr;
    for (rr = m->ResourceRecords; rr; rr=rr->next)
        if (rr->resrec.RecordType > kDNSRecordTypeDeregistering)
            if (TfrRecordToNIC(rr))
            {
                records[count].sixtyfourbits = zeroOpaque64;
                records[count].ptr = p;
                if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
                    rr->resrec.rrclass |= kDNSClass_UniqueRRSet;    // Temporarily set the 'unique' bit so PutResourceRecord will set it
                p = PutResourceRecordTTLWithLimit(msg, p, &msg->h.mDNS_numUpdates, &rr->resrec, rr->resrec.rroriginalttl, limit);
                rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet;       // Make sure to clear 'unique' bit back to normal state
                LogSPS("GetProxyRecords: %3d start %p end %p size %5d total %5d %s",
                       count, records[count].ptr, p, p - (mDNSu8 *)records[count].ptr, p - msg->data, ARDisplayString(m,rr));
                count++;
            }
    *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 mStatus ActivateLocalProxy(mDNS *const m, char *ifname)  // Called with the lock held
{
    mStatus result = mStatus_UnknownErr;
    io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOBSDNameMatching(kIOMasterPortDefault, 0, ifname));
    if (!service) { LogMsg("ActivateLocalProxy: No service for interface %s", ifname); return(mStatus_UnknownErr); }

    io_name_t n1, n2;
    IOObjectGetClass(service, n1);
    io_object_t parent;
    kern_return_t kr = IORegistryEntryGetParentEntry(service, kIOServicePlane, &parent);
    if (kr != KERN_SUCCESS) LogMsg("ActivateLocalProxy: IORegistryEntryGetParentEntry for %s/%s failed %d", ifname, n1, kr);
    else
    {
        IOObjectGetClass(parent, n2);
        LogSPS("ActivateLocalProxy: Interface %s service %s parent %s", ifname, n1, n2);
        const CFTypeRef ref = IORegistryEntryCreateCFProperty(parent, CFSTR(mDNS_IOREG_KEY), kCFAllocatorDefault, mDNSNULL);
        if (!ref) LogSPS("ActivateLocalProxy: No mDNS_IOREG_KEY for interface %s/%s/%s", ifname, n1, n2);
        else
        {
            if (CFGetTypeID(ref) != CFStringGetTypeID() || !CFEqual(ref, CFSTR(mDNS_IOREG_VALUE)))
                LogMsg("ActivateLocalProxy: mDNS_IOREG_KEY for interface %s/%s/%s value %s != %s",
                       ifname, n1, n2, CFStringGetCStringPtr(ref, mDNSNULL), mDNS_IOREG_VALUE);
            else if (!UseInternalSleepProxy)
                LogSPS("ActivateLocalProxy: Not using internal (NIC) sleep proxy for interface %s", ifname);
            else
            {
                io_connect_t conObj;
                kr = IOServiceOpen(parent, mach_task_self(), mDNS_USER_CLIENT_CREATE_TYPE, &conObj);
                if (kr != KERN_SUCCESS) LogMsg("ActivateLocalProxy: IOServiceOpen for %s/%s/%s failed %d", ifname, n1, n2, kr);
                else
                {
                    mDNSOffloadCmd cmd;
                    mDNSPlatformMemZero(&cmd, sizeof(cmd)); // When compiling 32-bit, make sure top 32 bits of 64-bit pointers get initialized to zero
                    cmd.command       = cmd_mDNSOffloadRR;
                    cmd.numUDPPorts   = GetPortArray(m, mDNSTransport_UDP, mDNSNULL);
                    cmd.numTCPPorts   = GetPortArray(m, mDNSTransport_TCP, mDNSNULL);
                    cmd.numRRRecords  = CountProxyRecords(m, &cmd.rrBufferSize);
                    cmd.compression   = sizeof(DNSMessageHeader);

                    DNSMessage *msg = (DNSMessage *)mallocL("mDNSOffloadCmd msg", sizeof(DNSMessageHeader) + cmd.rrBufferSize);
                    cmd.rrRecords.ptr = mallocL("mDNSOffloadCmd rrRecords", cmd.numRRRecords * sizeof(FatPtr));
                    cmd.udpPorts.ptr = mallocL("mDNSOffloadCmd udpPorts",  cmd.numUDPPorts  * sizeof(mDNSIPPort));
                    cmd.tcpPorts.ptr = mallocL("mDNSOffloadCmd tcpPorts",  cmd.numTCPPorts  * sizeof(mDNSIPPort));

                    LogSPS("ActivateLocalProxy: msg %p %d RR %p %d, UDP %p %d, TCP %p %d",
                           msg, cmd.rrBufferSize,
                           cmd.rrRecords.ptr, cmd.numRRRecords,
                           cmd.udpPorts.ptr, cmd.numUDPPorts,
                           cmd.tcpPorts.ptr, cmd.numTCPPorts);

                    if (!msg || !cmd.rrRecords.ptr || !cmd.udpPorts.ptr || !cmd.tcpPorts.ptr)
                        LogMsg("ActivateLocalProxy: Failed to allocate memory: msg %p %d RR %p %d, UDP %p %d, TCP %p %d",
                               msg, cmd.rrBufferSize,
                               cmd.rrRecords.ptr, cmd.numRRRecords,
                               cmd.udpPorts.ptr, cmd.numUDPPorts,
                               cmd.tcpPorts.ptr, cmd.numTCPPorts);
                    else
                    {
                        GetProxyRecords(m, msg, &cmd.rrBufferSize, cmd.rrRecords.ptr);
                        GetPortArray(m, mDNSTransport_UDP, cmd.udpPorts.ptr);
                        GetPortArray(m, mDNSTransport_TCP, cmd.tcpPorts.ptr);
                        char outputData[2];
                        size_t outputDataSize = sizeof(outputData);
                        kr = IOConnectCallStructMethod(conObj, 0, &cmd, sizeof(cmd), outputData, &outputDataSize);
                        LogSPS("ActivateLocalProxy: IOConnectCallStructMethod for %s/%s/%s %d", ifname, n1, n2, kr);
                        if (kr == KERN_SUCCESS) result = mStatus_NoError;
                    }

                    if (cmd.tcpPorts.ptr) freeL("mDNSOffloadCmd udpPorts",  cmd.tcpPorts.ptr);
                    if (cmd.udpPorts.ptr) freeL("mDNSOffloadCmd tcpPorts",  cmd.udpPorts.ptr);
                    if (cmd.rrRecords.ptr) freeL("mDNSOffloadCmd rrRecords", cmd.rrRecords.ptr);
                    if (msg) freeL("mDNSOffloadCmd msg",       msg);
                    IOServiceClose(conObj);
                }
            }
            CFRelease(ref);
        }
        IOObjectRelease(parent);
    }
    IOObjectRelease(service);
    return result;
}

#endif // APPLE_OSX_mDNSResponder

static io_service_t g_rootdomain = MACH_PORT_NULL;

mDNSlocal mDNSBool SystemWakeForNetworkAccess(void)
{
    mDNSs32 val = 0;
    CFBooleanRef clamshellStop = NULL;
    mDNSBool retnow = mDNSfalse;

    if (DisableSleepProxyClient) { LogSPS("SystemWakeForNetworkAccess: Sleep Proxy Client disabled by command-line option"); return mDNSfalse; }

    GetCurrentPMSetting(CFSTR("Wake On LAN"), &val);
    LogSPS("SystemWakeForNetworkAccess: Wake On LAN: %d", val);
    if (!val) return mDNSfalse;

    if (!g_rootdomain) g_rootdomain = IORegistryEntryFromPath(MACH_PORT_NULL, kIOPowerPlane ":/IOPowerConnection/IOPMrootDomain");
    if (!g_rootdomain) { LogMsg("SystemWakeForNetworkAccess: IORegistryEntryFromPath failed; assuming no clamshell so can WOMP"); return mDNStrue; }

    clamshellStop = (CFBooleanRef)IORegistryEntryCreateCFProperty(g_rootdomain, CFSTR(kAppleClamshellStateKey), kCFAllocatorDefault, 0);
    if (!clamshellStop) { LogSPS("SystemWakeForNetworkAccess: kAppleClamshellStateKey does not exist; assuming no clamshell so can WOMP"); return mDNStrue; }
    retnow = clamshellStop == kCFBooleanFalse;
    CFRelease(clamshellStop);
    if (retnow) { LogSPS("SystemWakeForNetworkAccess: kAppleClamshellStateKey is false; clamshell is open so can WOMP"); return mDNStrue; }

    clamshellStop = (CFBooleanRef)IORegistryEntryCreateCFProperty(g_rootdomain, CFSTR(kAppleClamshellCausesSleepKey), kCFAllocatorDefault, 0);
    if (!clamshellStop) { LogSPS("SystemWakeForNetworkAccess: kAppleClamshellCausesSleepKey does not exist; assuming no clamshell so can WOMP"); return mDNStrue; }
    retnow = (clamshellStop == kCFBooleanFalse);
    CFRelease(clamshellStop);
    if (retnow) { LogSPS("SystemWakeForNetworkAccess: kAppleClamshellCausesSleepKey is false; clamshell is closed but can WOMP"); return mDNStrue; }

    LogSPS("SystemWakeForNetworkAccess: clamshell is closed and can't WOMP");
    return mDNSfalse;
}

mDNSlocal mDNSBool SystemSleepOnlyIfWakeOnLAN(void)
{
    mDNSs32 val = 0;
    GetCurrentPMSetting(CFSTR("PrioritizeNetworkReachabilityOverSleep"), &val);
    return val != 0 ? mDNStrue : mDNSfalse;
}

#if APPLE_OSX_mDNSResponder
// When sleeping, we always ensure that the _autotunnel6 record (if connected to RR relay)
// gets deregistered, so that older peers are forced to connect over direct UDP instead of
// the RR relay.
//
// When sleeping w/o a successful AutoTunnel NAT Mapping, we ensure that all our BTMM
// service records are deregistered, so they do not appear in peers' Finder sidebars.
// We do this by checking for the (non-autotunnel) SRV records, as the PTR and TXT records
// depend on their associated SRV record and therefore will be deregistered together in a
// single update with the SRV record.
//
// Also, the per-zone _kerberos TXT record is always there, including while sleeping, so
// its presence shouldn't delay sleep.
//
// Note that the order of record deregistration is: first _autotunnel6 (if connected to RR
// relay) and host records get deregistered, then SRV (UpdateAllSrvRecords), PTR and TXT.
//
// Also note that returning false here will not delay sleep past the maximum of 10 seconds.
mDNSexport mDNSBool RecordReadyForSleep(mDNS *const m, AuthRecord *rr)
{
    if (!AuthRecord_uDNS(rr)) return mDNStrue;
    
    if ((rr->resrec.rrtype == kDNSType_AAAA) && SameDomainLabel(rr->namestorage.c, (const mDNSu8 *)"\x0c_autotunnel6"))
    {
        LogInfo("RecordReadyForSleep: %s not ready for sleep", ARDisplayString(m, rr));
        return mDNSfalse;
    }
    
    if ((mDNSIPPortIsZero(m->AutoTunnelNAT.ExternalPort) || m->AutoTunnelNAT.Result))
    {
        if (rr->resrec.rrtype == kDNSType_SRV && rr->state != regState_NoTarget && rr->zone
            && !SameDomainLabel(rr->namestorage.c, (const mDNSu8 *)"\x0b_autotunnel"))
        {
            DomainAuthInfo *info = GetAuthInfoForName_internal(m, rr->zone);
            if (info && info->AutoTunnel)
            {
                LogInfo("RecordReadyForSleep: %s not ready for sleep", ARDisplayString(m, rr));
                return mDNSfalse;
            }
        }
    }
    
    return mDNStrue;
}

// Caller must hold the lock
mDNSexport void RemoveAutoTunnel6Record(mDNS *const m)
{
    DomainAuthInfo *info;
    // Set the address to zero before calling UpdateAutoTunnel6Record, so that it will
    // deregister the record, and the MemFree callback won't re-register.
    m->AutoTunnelRelayAddr = zerov6Addr;
    for (info = m->AuthInfoList; info; info = info->next)
        if (info->AutoTunnel)
            UpdateAutoTunnel6Record(m, info);
}

mDNSlocal mDNSBool IPv6AddressIsOnInterface(mDNSv6Addr ipv6Addr, char *ifname)
{
    struct ifaddrs  *ifa;
    struct ifaddrs  *ifaddrs;
    mDNSAddr addr;

    if (if_nametoindex(ifname) == 0) {LogInfo("IPv6AddressIsOnInterface: Invalid name %s", ifname); return mDNSfalse;}

    if (getifaddrs(&ifaddrs) < 0) {LogInfo("IPv6AddressIsOnInterface: getifaddrs failed"); return mDNSfalse;}

    for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next)
    {
        if (strncmp(ifa->ifa_name, ifname, IFNAMSIZ) != 0)
            continue;
        if ((ifa->ifa_flags & IFF_UP) == 0 || !ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET6)
            continue;
        if (SetupAddr(&addr, ifa->ifa_addr) != mStatus_NoError)
        {
            LogInfo("IPv6AddressIsOnInterface: SetupAddr error, continuing to the next address");
            continue;
        }
        if (mDNSSameIPv6Address(ipv6Addr, *(mDNSv6Addr*)&addr.ip.v6))
        {
            LogInfo("IPv6AddressIsOnInterface: found %.16a", &ipv6Addr);
            break;
        }
    }
    freeifaddrs(ifaddrs);
    return ifa != NULL;
}

mDNSlocal mDNSv6Addr IPv6AddressFromString(char* buf)
{
    mDNSv6Addr retVal;
    struct addrinfo hints;
    struct addrinfo *res0;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET6;
    hints.ai_flags = AI_NUMERICHOST;

    int err = getaddrinfo(buf, NULL, &hints, &res0);
    if (err)
        return zerov6Addr;

    retVal = *(mDNSv6Addr*)&((struct sockaddr_in6*)res0->ai_addr)->sin6_addr;

    freeaddrinfo(res0);

    return retVal;
}

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);
    if (!connd)
    {
        LogInfo("CopyConnectivityBackToMyMacDict: SCDynamicStoreCopyValue failed: %s", SCErrorString(SCError()));
        goto end;
    }

    BTMMDict = CFDictionaryGetValue(connd, CFSTR("BackToMyMac"));
    if (!BTMMDict)
    {
        LogInfo("CopyConnectivityBackToMyMacDict: CFDictionaryGetValue: No value for BackToMyMac");
        goto end;
    }

    // Non-dictionary is treated as non-existent dictionary
    if (CFGetTypeID(BTMMDict) != CFDictionaryGetTypeID())
    {
        BTMMDict = NULL;
        LogMsg("CopyConnectivityBackToMyMacDict: BackToMyMac not a dictionary");
        goto end;
    }

    CFRetain(BTMMDict);

end:
    if (connd) CFRelease(connd);
    if (store) CFRelease(store);

    return BTMMDict;
}

#define MAX_IPV6_TEXTUAL 40

mDNSlocal mDNSv6Addr ParseBackToMyMacAddr(CFDictionaryRef BTMMDict, CFStringRef ifKey, CFStringRef addrKey)
{
    mDNSv6Addr retVal = zerov6Addr;
    CFTypeRef string = NULL;
    char ifname[IFNAMSIZ];
    char address[MAX_IPV6_TEXTUAL];

    if (!BTMMDict)
        return zerov6Addr;

    if (!CFDictionaryGetValueIfPresent(BTMMDict, ifKey, &string))
    {
        LogInfo("ParseBackToMyMacAddr: interface key does not exist");
        return zerov6Addr;
    }

    if (!CFStringGetCString(string, ifname, IFNAMSIZ, kCFStringEncodingUTF8))
    {
        LogMsg("ParseBackToMyMacAddr: Could not convert interface to CString");
        return zerov6Addr;
    }

    if (!CFDictionaryGetValueIfPresent(BTMMDict, addrKey, &string))
    {
        LogMsg("ParseBackToMyMacAddr: address key does not exist, but interface key does");
        return zerov6Addr;
    }

    if (!CFStringGetCString(string, address, sizeof(address), kCFStringEncodingUTF8))
    {
        LogMsg("ParseBackToMyMacAddr: Could not convert address to CString");
        return zerov6Addr;
    }

    retVal = IPv6AddressFromString(address);
    LogInfo("ParseBackToMyMacAddr: %s (%s) %.16a", ifname, address, &retVal);

    if (mDNSIPv6AddressIsZero(retVal))
        return zerov6Addr;

    if (!IPv6AddressIsOnInterface(retVal, ifname))
    {
        LogMsg("ParseBackToMyMacAddr: %.16a is not on %s", &retVal, ifname);
        return zerov6Addr;
    }

    return retVal;
}

mDNSlocal CFDictionaryRef GetBackToMyMacZones(CFDictionaryRef BTMMDict)
{
    CFTypeRef zones = NULL;

    if (!BTMMDict)
        return NULL;

    if (!CFDictionaryGetValueIfPresent(BTMMDict, CFSTR("Zones"), &zones))
    {
        LogInfo("CopyBTMMZones: Zones key does not exist");
        return NULL;
    }

    return zones;
}

mDNSlocal mDNSv6Addr ParseBackToMyMacZone(CFDictionaryRef zones, DomainAuthInfo* info)
{
    mDNSv6Addr addr = zerov6Addr;
    char buffer[MAX_ESCAPED_DOMAIN_NAME];
    CFStringRef domain = NULL;
    CFTypeRef theZone = NULL;

    if (!zones)
        return addr;

    ConvertDomainNameToCString(&info->domain, buffer);
    domain = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
    if (!domain)
        return addr;

    if (CFDictionaryGetValueIfPresent(zones, domain, &theZone))
        addr = ParseBackToMyMacAddr(theZone, CFSTR("Interface"), CFSTR("Address"));

    CFRelease(domain);

    return addr;
}

mDNSlocal void SetupBackToMyMacInnerAddresses(mDNS *const m, CFDictionaryRef BTMMDict)
{
    DomainAuthInfo* info;
    CFDictionaryRef zones = GetBackToMyMacZones(BTMMDict);
    mDNSv6Addr newAddr;

    for (info = m->AuthInfoList; info; info = info->next)
    {
        if (!info->AutoTunnel)
            continue;

        newAddr = ParseBackToMyMacZone(zones, info);

        if (mDNSSameIPv6Address(newAddr, info->AutoTunnelInnerAddress))
            continue;

        info->AutoTunnelInnerAddress = newAddr;
        DeregisterAutoTunnelHostRecord(m, info);
        UpdateAutoTunnelHostRecord(m, info);
        UpdateAutoTunnelDomainStatus(m, info);
    }
}

// MUST be called holding the lock
mDNSlocal void ProcessConndConfigChanges(mDNS *const m)
{
    CFDictionaryRef dict = CopyConnectivityBackToMyMacDict();
    if (!dict)
        LogInfo("ProcessConndConfigChanges: No BTMM dictionary");
    mDNSv6Addr relayAddr = ParseBackToMyMacAddr(dict, CFSTR("RelayInterface"), CFSTR("RelayAddress"));

    LogInfo("ProcessConndConfigChanges: relay %.16a", &relayAddr);

    SetupBackToMyMacInnerAddresses(m, dict);

    if (dict) CFRelease(dict);

    if (!mDNSSameIPv6Address(relayAddr, m->AutoTunnelRelayAddr))
    {
        m->AutoTunnelRelayAddr = relayAddr;

        DomainAuthInfo* info;
        for (info = m->AuthInfoList; info; info = info->next)
            if (info->AutoTunnel)
            {
                DeregisterAutoTunnel6Record(m, info);
                UpdateAutoTunnel6Record(m, info);
                UpdateAutoTunnelDomainStatus(m, info);
            }

        // Determine whether we need racoon to accept incoming connections
        UpdateAnonymousRacoonConfig(m);
    }

    // If awacsd crashes or exits for some reason, restart it
    UpdateBTMMRelayConnection(m);
}
#endif /* APPLE_OSX_mDNSResponder */


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
    mDNSs32 utc = mDNSPlatformUTC();
    m->SystemWakeOnLANEnabled = SystemWakeForNetworkAccess();
    m->SystemSleepOnlyIfWakeOnLAN = SystemSleepOnlyIfWakeOnLAN();
    MarkAllInterfacesInactive(m, utc);
    UpdateInterfaceList(m, utc);
    ClearInactiveInterfaces(m, utc);
    SetupActiveInterfaces(m, utc);

#if APPLE_OSX_mDNSResponder
    mDNS_Lock(m);
    ProcessConndConfigChanges(m);
    mDNS_Unlock(m);

    // Scan to find client tunnels whose questions have completed,
    // but whose local inner/outer addresses have changed since the tunnel was set up
    ClientTunnel *p;
    for (p = m->TunnelClients; p; p = p->next)
        if (p->q.ThisQInterval < 0)
        {
            DomainAuthInfo* info = GetAuthInfoForName(m, &p->dstname);
            if (!info)
            {
                LogMsg("mDNSMacOSXNetworkChanged: Could not get AuthInfo for %##s, removing tunnel keys", p->dstname.c);
                AutoTunnelSetKeys(p, mDNSfalse);
            }
            else
            {
                mDNSv6Addr inner = info->AutoTunnelInnerAddress;

                if (!mDNSIPPortIsZero(p->rmt_outer_port))
                {
                    mDNSAddr tmpSrc = zeroAddr;
                    mDNSAddr tmpDst = { mDNSAddrType_IPv4, {{{0}}} };
                    tmpDst.ip.v4 = p->rmt_outer;
                    mDNSPlatformSourceAddrForDest(&tmpSrc, &tmpDst);
                    if (!mDNSSameIPv6Address(p->loc_inner, inner) ||
                        !mDNSSameIPv4Address(p->loc_outer, tmpSrc.ip.v4))
                    {
                        AutoTunnelSetKeys(p, mDNSfalse);
                        p->loc_inner = inner;
                        p->loc_outer = tmpSrc.ip.v4;
                        AutoTunnelSetKeys(p, mDNStrue);
                    }
                }
                else
                {
                    if (!mDNSSameIPv6Address(p->loc_inner, inner) ||
                        !mDNSSameIPv6Address(p->loc_outer6, m->AutoTunnelRelayAddr))
                    {
                        AutoTunnelSetKeys(p, mDNSfalse);
                        p->loc_inner = inner;
                        p->loc_outer6 = m->AutoTunnelRelayAddr;
                        AutoTunnelSetKeys(p, mDNStrue);
                    }
                }
            }
        }

    SetSPS(m);

    NetworkInterfaceInfoOSX *i;
    for (i = m->p->InterfaceList; i; i = i->next)
    {
        if (!m->SPSSocket)      // Not being Sleep Proxy Server; close any open BPF fds
        {
            if (i->BPF_fd >= 0 && CountProxyTargets(m, i, mDNSNULL, mDNSNULL) == 0) CloseBPF(i);
        }
        else                                // else, we're Sleep Proxy Server; open BPF fds
        {
            if (i->Exists && i->Registered == i && i->ifinfo.McastTxRx && !(i->ifa_flags & IFF_LOOPBACK) && i->BPF_fd == -1)
            { LogSPS("%s requesting BPF", i->ifinfo.ifname); i->BPF_fd = -2; mDNSRequestBPF(); }
        }
    }

#endif // APPLE_OSX_mDNSResponder

    uDNS_SetupDNSConfig(m);
    mDNS_ConfigChanged(m);
}

// Called with KQueueLock & mDNS lock
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);
    }
}

// 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
//   Setup:/Network/Service/<servicename>/Interface
mDNSlocal CFStringRef CopyNameFromKey(CFStringRef key)
{
    CFArrayRef a;
    CFStringRef name = NULL;

    a = CFStringCreateArrayBySeparatingStrings(NULL, key, CFSTR("/"));
    if (a && CFArrayGetCount(a) == 5) name = CFRetain(CFArrayGetValueAtIndex(a, 3));
    if (a != NULL) CFRelease(a);

    return name;
}

// Whether a key from a network change notification corresponds to
// an IP service that is explicitly configured for IPv4 Link Local
mDNSlocal mDNSBool ChangedKeysHaveIPv4LL(CFArrayRef inkeys)
{
    SCDynamicStoreRef store = NULL;
    CFDictionaryRef dict = NULL;
    CFMutableArrayRef a;
    const void **keys = NULL, **vals = NULL;
    CFStringRef pattern = NULL;
    int i, ic, j, jc;
    mDNSBool found = mDNSfalse;

    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;

    // Setup:/Network/Service/[^/]+/Interface
    pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, kSCCompAnyRegex, kSCEntNetInterface);
    if (pattern == NULL) goto done;
    CFArrayAppendValue(a, pattern);
    CFRelease(pattern);

    // Setup:/Network/Service/[^/]+/IPv4
    pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, kSCCompAnyRegex, kSCEntNetIPv4);
    if (pattern == NULL) goto done;
    CFArrayAppendValue(a, pattern);
    CFRelease(pattern);

    dict = SCDynamicStoreCopyMultiple(store, NULL, a);
    CFRelease(a);

    if (!dict)
    {
        LogMsg("ChangedKeysHaveIPv4LL: Empty dictionary");
        goto done;
    }

    ic = CFDictionaryGetCount(dict);
    vals = mDNSPlatformMemAllocate(sizeof (void *) * ic);
    keys = mDNSPlatformMemAllocate(sizeof (void *) * ic);
    CFDictionaryGetKeysAndValues(dict, keys, vals);

    for (j = 0; j < jc && !found; j++)
    {
        CFStringRef key = CFArrayGetValueAtIndex(inkeys, j);
        CFStringRef ifname = NULL;

        char buf[256];

        // It would be nice to use a regex here
        if (!CFStringHasPrefix(key, CFSTR("State:/Network/Interface/")) || !CFStringHasSuffix(key, kSCEntNetIPv4)) continue;

        if ((ifname = CopyNameFromKey(key)) == NULL) continue;
        if (mDNS_LoggingEnabled)
        {
            if (!CFStringGetCString(ifname, buf, sizeof(buf), kCFStringEncodingUTF8)) buf[0] = 0;
            LogInfo("ChangedKeysHaveIPv4LL: potential ifname %s", buf);
        }

        for (i = 0; i < ic; i++)
        {
            CFDictionaryRef ipv4dict;
            CFStringRef name;
            CFStringRef serviceid;
            CFStringRef configmethod;

            if (!CFStringHasSuffix(keys[i], kSCEntNetInterface)) continue;

            if (CFDictionaryGetTypeID() != CFGetTypeID(vals[i])) continue;

            if ((name = CFDictionaryGetValue(vals[i], kSCPropNetInterfaceDeviceName)) == NULL) continue;

            if (!CFEqual(ifname, name)) continue;

            if ((serviceid = CopyNameFromKey(keys[i])) == NULL) continue;
            if (mDNS_LoggingEnabled)
            {
                if (!CFStringGetCString(serviceid, buf, sizeof(buf), kCFStringEncodingUTF8)) buf[0] = 0;
                LogInfo("ChangedKeysHaveIPv4LL: found serviceid %s", buf);
            }

            pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, serviceid, kSCEntNetIPv4);
            CFRelease(serviceid);
            if (pattern == NULL) continue;

            ipv4dict = CFDictionaryGetValue(dict, pattern);
            CFRelease(pattern);
            if (!ipv4dict || CFDictionaryGetTypeID() != CFGetTypeID(ipv4dict)) continue;

            configmethod = CFDictionaryGetValue(ipv4dict, kSCPropNetIPv4ConfigMethod);
            if (!configmethod) continue;

            if (mDNS_LoggingEnabled)
            {
                if (!CFStringGetCString(configmethod, buf, sizeof(buf), kCFStringEncodingUTF8)) buf[0] = 0;
                LogInfo("ChangedKeysHaveIPv4LL: configmethod %s", buf);
            }

            if (CFEqual(configmethod, kSCValNetIPv4ConfigMethodLinkLocal)) { found = mDNStrue; break; }
        }

        CFRelease(ifname);
    }

done:
    if (vals != NULL) mDNSPlatformMemFree(vals);
    if (keys != NULL) mDNSPlatformMemFree(keys);
    if (dict != NULL) CFRelease(dict);
    if (store != NULL) CFRelease(store);

    return found;
}

mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
{
    (void)store;        // Parameter not used
    mDNSBool changeNow = mDNSfalse;
    mDNS *const m = (mDNS *const)context;
    KQueueLock(m);
    mDNS_Lock(m);

    mDNSs32 delay = mDNSPlatformOneSecond * 2;              // Start off assuming a two-second 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_DynamicDNS  ) != 0);
    int c4 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_DNS         ) != 0);
    if (c && c - c1 - c2 - c3 - c4 == 0) delay = mDNSPlatformOneSecond/10;  // If these were the only changes, shorten delay

    {
        int i;
        for (i=0; i<c; i++)
        {
            char buf[256];
            if (!CFStringGetCString(CFArrayGetValueAtIndex(changedKeys, i), buf, sizeof(buf), kCFStringEncodingUTF8)) buf[0] = 0;
            if (buf[0])
            {
                if (strstr(buf, "p2p"))
                {
                    LogInfo("NetworkChanged SC key: %s, not delaying network change", buf);
                    changeNow = mDNStrue;
                    break;
                }
            }
        }
    }

    if (mDNS_LoggingEnabled)
    {
        int i;
        for (i=0; i<c; i++)
        {
            char buf[256];
            if (!CFStringGetCString(CFArrayGetValueAtIndex(changedKeys, i), buf, sizeof(buf), kCFStringEncodingUTF8)) buf[0] = 0;
            LogInfo("***   NetworkChanged SC key: %s", buf);
        }
        LogInfo("***   NetworkChanged   *** %d change%s %s%s%s%sdelay %d",
                c, c>1 ? "s" : "",
                c1 ? "(Local Hostname) " : "",
                c2 ? "(Computer Name) "  : "",
                c3 ? "(DynamicDNS) "     : "",
                c4 ? "(DNS) "            : "",
                delay);
    }

    mDNSBool btmmChanged = CFArrayContainsValue(changedKeys, range, NetworkChangedKey_BackToMyMac);
    if (btmmChanged) delay = 0;

    SetNetworkChanged(m, delay);

    // Other software might pick up these changes to register or browse in WAB or BTMM domains,
    // so in order for secure updates to be made to the server, make sure to read the keychain and
    // 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 (c3 || btmmChanged)
        SetKeyChainTimer(m, delay);

    mDNS_Unlock(m);

    // If DNS settings changed, immediately force a reconfig (esp. cache flush)
    // Similarly, if an interface changed that is explicitly IPv4 link local, immediately force a reconfig
    if (c4 || ChangedKeysHaveIPv4LL(changedKeys) || changeNow) mDNSMacOSXNetworkChanged(m);

    KQueueUnlock(m, "NetworkChanged");
}

#if APPLE_OSX_mDNSResponder
mDNSlocal void RefreshSPSStatus(const void *key, const void *value, void *context)
{
    (void)context;
    char buf[IFNAMSIZ];

    CFStringRef ifnameStr = (CFStringRef)key;
    CFArrayRef array = (CFArrayRef)value;
    if (!CFStringGetCString(ifnameStr, buf, sizeof(buf), kCFStringEncodingUTF8)) buf[0] = 0;

    LogInfo("RefreshSPSStatus: Updating SPS state for key %s, array count %d", buf, CFArrayGetCount(array));
    mDNSDynamicStoreSetConfig(kmDNSSleepProxyServersState, buf, value);
}
#endif

mDNSlocal void DynamicStoreReconnected(SCDynamicStoreRef store, void *info)
{
    mDNS *const m = (mDNS *const)info;
    (void)store;

    LogInfo("DynamicStoreReconnected: Reconnected");

    // State:/Network/MulticastDNS
    SetLocalDomains();

    // State:/Network/DynamicDNS
    if (m->FQDN.c[0])
        mDNSPlatformDynDNSHostNameStatusChanged(&m->FQDN, 1);

    // Note: PrivateDNS and BackToMyMac are automatically populated when configd is restarted
    // as we receive network change notifications and thus not necessary. But we leave it here
    // so that if things are done differently in the future, this code still works.

    // State:/Network/PrivateDNS
    CFMutableArrayRef sa = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
    if (!sa)
        LogMsg("DynamicStoreReconnected:PrivateDNS: CFArrayCreateMutable failed");
    else
    {
        DomainAuthInfo *FoundInList;
        char stringbuf[MAX_ESCAPED_DOMAIN_NAME];    // Max legal domainname as C-string, including terminating NUL
        for (FoundInList = m->AuthInfoList; FoundInList; FoundInList = FoundInList->next)
        {
            ConvertDomainNameToCString(&FoundInList->domain, stringbuf);
            CFStringRef cfs = CFStringCreateWithCString(NULL, stringbuf, kCFStringEncodingUTF8);
            if (cfs) { CFArrayAppendValue(sa, cfs); CFRelease(cfs); }
        }
        mDNSDynamicStoreSetConfig(kmDNSPrivateConfig, mDNSNULL, sa);
        CFRelease(sa);
    }

    // State:/Network/BackToMyMac
#if APPLE_OSX_mDNSResponder
    mDNS_Lock(m);
    UpdateAutoTunnelDomainStatuses(m);
    mDNS_Unlock(m);

    // State:/Network/Interface/en0/SleepProxyServers
    if (spsStatusDict) CFDictionaryApplyFunction(spsStatusDict, RefreshSPSStatus, NULL);
#endif
}

mDNSlocal mStatus WatchForNetworkChanges(mDNS *const m)
{
    mStatus err = -1;
    SCDynamicStoreContext context = { 0, m, NULL, NULL, NULL };
    SCDynamicStoreRef store    = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:WatchForNetworkChanges"), NetworkChanged, &context);
    CFMutableArrayRef keys     = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
    CFStringRef pattern1 = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4);
    CFStringRef pattern2 = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv6);
    CFMutableArrayRef patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);

    if (!store) { LogMsg("SCDynamicStoreCreate failed: %s", SCErrorString(SCError())); goto error; }
    if (!keys || !pattern1 || !pattern2 || !patterns) goto error;

    CFArrayAppendValue(keys, NetworkChangedKey_IPv4);
    CFArrayAppendValue(keys, NetworkChangedKey_IPv6);
    CFArrayAppendValue(keys, NetworkChangedKey_Hostnames);
    CFArrayAppendValue(keys, NetworkChangedKey_Computername);
    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_BTMMConnectivity);
    CFArrayAppendValue(keys, NetworkChangedKey_InternetSharing);
    CFArrayAppendValue(patterns, pattern1);
    CFArrayAppendValue(patterns, pattern2);
    CFArrayAppendValue(patterns, CFSTR("State:/Network/Interface/[^/]+/AirPort"));
    if (!SCDynamicStoreSetNotificationKeys(store, keys, patterns))
    { LogMsg("SCDynamicStoreSetNotificationKeys failed: %s", SCErrorString(SCError())); goto error; }

#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
    if (!SCDynamicStoreSetDispatchQueue(store, dispatch_get_main_queue()))
    { LogMsg("SCDynamicStoreCreateRunLoopSource failed: %s", SCErrorString(SCError())); goto error; }
#else
    m->p->StoreRLS = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
    if (!m->p->StoreRLS) { LogMsg("SCDynamicStoreCreateRunLoopSource failed: %s", SCErrorString(SCError())); goto error; }
    CFRunLoopAddSource(CFRunLoopGetCurrent(), m->p->StoreRLS, kCFRunLoopDefaultMode);
#endif
    SCDynamicStoreSetDisconnectCallBack(store, DynamicStoreReconnected);
    m->p->Store = store;
    err = 0;
    goto exit;

error:
    if (store) CFRelease(store);

exit:
    if (patterns) CFRelease(patterns);
    if (pattern2) CFRelease(pattern2);
    if (pattern1) CFRelease(pattern1);
    if (keys) CFRelease(keys);

    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)
{
    AuthRecord  *rr;
    pfArray_t portArray;
    pfArray_t protocolArray;
    uint32_t count = 0;

    for (rr = m->ResourceRecords; rr; rr=rr->next)
    {
        if ((rr->resrec.rrtype == kDNSServiceType_SRV) && (rr->ARType == AuthRecordAnyIncludeP2P))
        {
            const mDNSu8    *p;

            if (count >= PFPortArraySize)
            {
                LogMsg("mDNSSetPacketFilterRules: %d service limit, skipping %s", PFPortArraySize, ARDisplayString(m, rr));
                continue;
            }

            if (excludeRecord && IdenticalResourceRecord(&rr->resrec, excludeRecord))
            {
                LogInfo("mDNSSetPacketFilterRules: record being removed, skipping %s", ARDisplayString(m, rr));
                continue;
            }

            LogInfo("mDNSSetPacketFilterRules: found %s", ARDisplayString(m, rr));

            portArray[count] = rr->resrec.rdata->u.srv.port.NotAnInteger;

            // Assume <Service Instance>.<App Protocol>.<Transport Protocol>.<Name>
            p = rr->resrec.name->c;

            // Skip to App Protocol
            if (p[0]) p += 1 + p[0];

            // Skip to Transport Protocol
            if (p[0]) p += 1 + p[0];

            if      (SameDomainLabel(p, (mDNSu8 *)"\x4" "_tcp")) protocolArray[count] = IPPROTO_TCP;
            else if (SameDomainLabel(p, (mDNSu8 *)"\x4" "_udp")) protocolArray[count] = IPPROTO_UDP;
            else
            {
                LogMsg("mDNSSetPacketFilterRules: could not determine transport protocol of service");
                LogMsg("mDNSSetPacketFilterRules: %s", ARDisplayString(m, rr));
                return;
            }
            count++;
        }
    }
    mDNSPacketFilterControl(PF_SET_RULES, ifname, count, portArray, protocolArray);
}

// If the p2p interface already exists, update the Bonjour packet filter rules for it.
mDNSexport void mDNSUpdatePacketFilter(const ResourceRecord *const excludeRecord)
{
    mDNS *const m = &mDNSStorage;

    NetworkInterfaceInfo *intf = GetFirstActiveInterface(m->HostInterfaces);
    while (intf)
    {
        if (strncmp(intf->ifname, "p2p", 3) == 0)
        {
            LogInfo("mDNSInitPacketFilter: Setting rules for ifname %s", intf->ifname);
            mDNSSetPacketFilterRules(m, intf->ifname, excludeRecord);
            break;
        }
        intf = GetFirstActiveInterface(intf->next);
    }
}

#else // !TARGET_OS_EMBEDDED

// Currently no packet filter setup required on embedded platforms.
mDNSexport void mDNSUpdatePacketFilter(const ResourceRecord *const excludeRecord)
{
    (void) excludeRecord; // unused
}

#endif // !TARGET_OS_EMBEDDED

// Handle AWDL KEV_DL_MASTER_ELECTED event by restarting queries and advertisements
// marked to include the AWDL interface.
mDNSlocal void newMasterElected(mDNS *const m, struct net_event_data * ptr)
{
    char        ifname[IFNAMSIZ];
    mDNSu32     interfaceIndex;
    DNSQuestion *q;
    AuthRecord  *rr;
    NetworkInterfaceInfoOSX *infoOSX;
    mDNSInterfaceID InterfaceID;

    snprintf(ifname, IFNAMSIZ, "%s%d", ptr->if_name, ptr->if_unit);
    interfaceIndex  = if_nametoindex(ifname);

    if (!interfaceIndex)
    {
        LogMsg("newMasterElected: if_nametoindex(%s) failed", ifname);
        return;
    }

    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");
        return;
    }
    InterfaceID = infoOSX->ifinfo.InterfaceID;

    for (q = m->Questions; q; q=q->next)
    {
        if ((!q->InterfaceID && (q->flags & kDNSServiceFlagsIncludeAWDL))
            || q->InterfaceID == InterfaceID)
        {
            LogInfo("newMasterElected: restarting %s query for %##s", DNSTypeName(q->qtype), q->qname.c);
            mDNSCoreRestartQuestion(m, q);
        }
    }

    for (rr = m->ResourceRecords; rr; rr=rr->next)
    {
        if ((!rr->resrec.InterfaceID && (rr->ARType == AuthRecordAnyIncludeAWDL))
           || rr->resrec.InterfaceID == InterfaceID)
        {
            LogInfo("newMasterElected: restarting %s announcements for %##s", DNSTypeName(rr->resrec.rrtype), rr->namestorage.c);
            mDNSCoreRestartRegistration(m, rr, -1);
        }
    }
}

// An ssth array of all zeroes indicates the peer has no services registered.
mDNSlocal mDNSBool allZeroSSTH(struct opaque_presence_indication *op)
{
    int i;
    int *intp = (int *) op->ssth;

    for (i = 0; i < (int)(MAX_SSTH_SIZE / sizeof(int)); i++, intp++)
    {
        if (*intp)
            return mDNSfalse;
    }
    return mDNStrue;
}

// Mark records from this peer for deletion from the cache.
mDNSlocal void removeCachedPeerRecords(mDNS *const m, mDNSu32 ifindex, mDNSAddr *ap)
{
    mDNSu32     slot;
    CacheGroup  *cg;
    CacheRecord *cr;
    mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(m, ifindex);

    if (!InterfaceID)
    {
        LogInfo("removeCachedPeerRecords: Invalid ifindex: %d", ifindex);
        return;
    }

    FORALL_CACHERECORDS(slot, cg, cr)
    {
        if ((InterfaceID == cr->resrec.InterfaceID) && mDNSSameAddress(ap, & cr->sourceAddress))
        {
            LogInfo("removeCachedPeerRecords: %s %##s marking for deletion",
                 DNSTypeName(cr->resrec.rrtype), cr->resrec.name->c);
            mDNS_PurgeCacheResourceRecord(m, cr);
        }
    }
}

// Handle KEV_DL_NODE_PRESENCE event.
mDNSlocal void nodePresence(mDNS *const m, 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");
 
    // 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.
    // We should have already flushed the cache when the previous
    // KEV_DL_NODE_ABSENCE was received or upon receipt of the goodbye packets
    // when the service was deregistered.  Thus, the following
    // cache flush logic is disabled by mDNSHandlePeerEvents being false
    // until we determine that a cache flush is required on receipt of this event.
    if (m->mDNSHandlePeerEvents && allZeroSSTH(op))
    {
        mDNSAddr    peerAddr;

        peerAddr.type = mDNSAddrType_IPv6;
        peerAddr.ip.v6 = *(mDNSv6Addr*)&p->sin6_node_address.sin6_addr;

        LogInfo("nodePresence: ssth is all zeroes, delete cached records from this peer");
        removeCachedPeerRecords(m, p->sdl_node_address.sdl_index, & peerAddr);
    }
}

// Handle KEV_DL_NODE_ABSENCE event.
mDNSlocal void nodeAbsence(mDNS *const m, 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: delete cached records from this peer");
    removeCachedPeerRecords(m, p->sdl_node_address.sdl_index, & peerAddr);
}

mDNSlocal void SysEventCallBack(int s1, short __unused filter, void *context)
{
    mDNS *const m = (mDNS *const)context;

    mDNS_Lock(m);

    struct { struct kern_event_msg k; char extra[256]; } msg;
    int bytes = recv(s1, &msg, sizeof(msg), 0);
    if (bytes < 0)
        LogMsg("SysEventCallBack: recv error %d errno %d (%s)", bytes, errno, strerror(errno));
    else
    {
        LogInfo("SysEventCallBack got %d bytes size %d %X %s %X %s %X %s id %d code %d %s",
                bytes, msg.k.total_size,
                msg.k.vendor_code, msg.k.vendor_code  == KEV_VENDOR_APPLE  ? "KEV_VENDOR_APPLE"  : "?",
                msg.k.kev_class, msg.k.kev_class    == KEV_NETWORK_CLASS ? "KEV_NETWORK_CLASS" : "?",
                msg.k.kev_subclass, msg.k.kev_subclass == KEV_DL_SUBCLASS   ? "KEV_DL_SUBCLASS"   : "?",
                msg.k.id, msg.k.event_code,
                msg.k.event_code == KEV_DL_SIFFLAGS             ? "KEV_DL_SIFFLAGS"             :
                msg.k.event_code == KEV_DL_SIFMETRICS           ? "KEV_DL_SIFMETRICS"           :
                msg.k.event_code == KEV_DL_SIFMTU               ? "KEV_DL_SIFMTU"               :
                msg.k.event_code == KEV_DL_SIFPHYS              ? "KEV_DL_SIFPHYS"              :
                msg.k.event_code == KEV_DL_SIFMEDIA             ? "KEV_DL_SIFMEDIA"             :
                msg.k.event_code == KEV_DL_SIFGENERIC           ? "KEV_DL_SIFGENERIC"           :
                msg.k.event_code == KEV_DL_ADDMULTI             ? "KEV_DL_ADDMULTI"             :
                msg.k.event_code == KEV_DL_DELMULTI             ? "KEV_DL_DELMULTI"             :
                msg.k.event_code == KEV_DL_IF_ATTACHED          ? "KEV_DL_IF_ATTACHED"          :
                msg.k.event_code == KEV_DL_IF_DETACHING         ? "KEV_DL_IF_DETACHING"         :
                msg.k.event_code == KEV_DL_IF_DETACHED          ? "KEV_DL_IF_DETACHED"          :
                msg.k.event_code == KEV_DL_LINK_OFF             ? "KEV_DL_LINK_OFF"             :
                msg.k.event_code == KEV_DL_LINK_ON              ? "KEV_DL_LINK_ON"              :
                msg.k.event_code == KEV_DL_PROTO_ATTACHED       ? "KEV_DL_PROTO_ATTACHED"       :
                msg.k.event_code == KEV_DL_PROTO_DETACHED       ? "KEV_DL_PROTO_DETACHED"       :
                msg.k.event_code == KEV_DL_LINK_ADDRESS_CHANGED ? "KEV_DL_LINK_ADDRESS_CHANGED" :
                msg.k.event_code == KEV_DL_WAKEFLAGS_CHANGED    ? "KEV_DL_WAKEFLAGS_CHANGED"    :
                msg.k.event_code == KEV_DL_IF_IDLE_ROUTE_REFCNT ? "KEV_DL_IF_IDLE_ROUTE_REFCNT" :
                msg.k.event_code == KEV_DL_IFCAP_CHANGED        ? "KEV_DL_IFCAP_CHANGED"        :
                msg.k.event_code == KEV_DL_LINK_QUALITY_METRIC_CHANGED    ? "KEV_DL_LINK_QUALITY_METRIC_CHANGED"    :
                msg.k.event_code == KEV_DL_NODE_PRESENCE        ? "KEV_DL_NODE_PRESENCE"        :
                msg.k.event_code == KEV_DL_NODE_ABSENCE         ? "KEV_DL_NODE_ABSENCE"         :
                msg.k.event_code == KEV_DL_MASTER_ELECTED       ? "KEV_DL_MASTER_ELECTED"       :
                 "?");

        if (msg.k.event_code == KEV_DL_NODE_PRESENCE)
            nodePresence(m, (struct kev_dl_node_presence *) &msg.k.event_data);

        if (msg.k.event_code == KEV_DL_NODE_ABSENCE)
            nodeAbsence(m, (struct kev_dl_node_absence *) &msg.k.event_data);

        if (msg.k.event_code == KEV_DL_MASTER_ELECTED)
            newMasterElected(m, (struct net_event_data *) &msg.k.event_data);
            
        // We receive network change notifications both through configd and through SYSPROTO_EVENT socket.
        // Configd may not generate network change events for manually configured interfaces (i.e., non-DHCP)
        // always during sleep/wakeup due to some race conditions (See radar:8666757). At the same time, if
        // "Wake on Network Access" is not turned on, the notification will not have KEV_DL_WAKEFLAGS_CHANGED.
        // Hence, during wake up, if we see a KEV_DL_LINK_ON (i.e., link is UP), we trigger a network change.

        if (msg.k.event_code == KEV_DL_WAKEFLAGS_CHANGED || msg.k.event_code == KEV_DL_LINK_ON)
            SetNetworkChanged(m, mDNSPlatformOneSecond * 2);

#if !TARGET_OS_EMBEDDED     // don't setup packet filter rules on embedded

        // For p2p interfaces, need to open the advertised service port in the firewall.
        if (msg.k.event_code == KEV_DL_IF_ATTACHED)
        {
            struct net_event_data   * p;
            p = (struct net_event_data *) &msg.k.event_data;

            if (strncmp(p->if_name, "p2p", 3) == 0)
            {
                char ifname[IFNAMSIZ];
                snprintf(ifname, IFNAMSIZ, "%s%d", p->if_name, p->if_unit);

                LogInfo("SysEventCallBack: KEV_DL_IF_ATTACHED if_family = %d, if_unit = %d, if_name = %s", p->if_family, p->if_unit, p->if_name);

                mDNSSetPacketFilterRules(m, ifname, NULL);
            }
        }

        // For p2p interfaces, need to clear the firewall rules on interface detach
        if (msg.k.event_code == KEV_DL_IF_DETACHED)
        {
            struct net_event_data   * p;
            p = (struct net_event_data *) &msg.k.event_data;

            if (strncmp(p->if_name, "p2p", 3) == 0)
            {
                pfArray_t portArray, protocolArray; // not initialized since count is 0 for PF_CLEAR_RULES
                char ifname[IFNAMSIZ];
                snprintf(ifname, IFNAMSIZ, "%s%d", p->if_name, p->if_unit);

                LogInfo("SysEventCallBack: KEV_DL_IF_DETACHED if_family = %d, if_unit = %d, if_name = %s", p->if_family, p->if_unit, p->if_name);

                mDNSPacketFilterControl(PF_CLEAR_RULES, ifname, 0, portArray, protocolArray);
            }
        }
#endif // !TARGET_OS_EMBEDDED

    }

    mDNS_Unlock(m);
}

mDNSlocal mStatus WatchForSysEvents(mDNS *const m)
{
    m->p->SysEventNotifier = socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT);
    if (m->p->SysEventNotifier < 0)
    { LogMsg("WatchForSysEvents: socket failed error %d errno %d (%s)", m->p->SysEventNotifier, errno, strerror(errno)); return(mStatus_NoMemoryErr); }

    struct kev_request kev_req = { KEV_VENDOR_APPLE, KEV_NETWORK_CLASS, KEV_DL_SUBCLASS };
    int err = ioctl(m->p->SysEventNotifier, SIOCSKEVFILT, &kev_req);
    if (err < 0)
    {
        LogMsg("WatchForSysEvents: SIOCSKEVFILT failed error %d errno %d (%s)", err, errno, strerror(errno));
        close(m->p->SysEventNotifier);
        m->p->SysEventNotifier = -1;
        return(mStatus_UnknownErr);
    }

    m->p->SysEventKQueue.KQcallback = SysEventCallBack;
    m->p->SysEventKQueue.KQcontext  = m;
    m->p->SysEventKQueue.KQtask     = "System Event Notifier";
    KQueueSet(m->p->SysEventNotifier, EV_ADD, EVFILT_READ, &m->p->SysEventKQueue);

    return(mStatus_NoError);
}

#ifndef NO_SECURITYFRAMEWORK
mDNSlocal OSStatus KeychainChanged(SecKeychainEvent keychainEvent, SecKeychainCallbackInfo *info, void *context)
{
    LogInfo("***   Keychain Changed   ***");
    mDNS *const m = (mDNS *const)context;
    SecKeychainRef skc;
    OSStatus err = SecKeychainCopyDefault(&skc);
    if (!err)
    {
        if (info->keychain == skc)
        {
            // For delete events, attempt to verify what item was deleted fail because the item is already gone, so we just assume they may be relevant
            mDNSBool relevant = (keychainEvent == kSecDeleteEvent);
            if (!relevant)
            {
                UInt32 tags[3] = { kSecTypeItemAttr, kSecServiceItemAttr, kSecAccountItemAttr };
                SecKeychainAttributeInfo attrInfo = { 3, tags, NULL };  // Count, array of tags, array of formats
                SecKeychainAttributeList *a = NULL;
                err = SecKeychainItemCopyAttributesAndData(info->item, &attrInfo, NULL, &a, NULL, NULL);
                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)))));
                    SecKeychainItemFreeAttributesAndData(a, NULL);
                }
            }
            if (relevant)
            {
                LogInfo("***   Keychain Changed   *** KeychainEvent=%d %s",
                        keychainEvent,
                        keychainEvent == kSecAddEvent    ? "kSecAddEvent"    :
                        keychainEvent == kSecDeleteEvent ? "kSecDeleteEvent" :
                        keychainEvent == kSecUpdateEvent ? "kSecUpdateEvent" : "<Unknown>");
                // We're running on the CFRunLoop (Mach port) thread, not the kqueue thread, so we need to grab the KQueueLock before proceeding
                KQueueLock(m);
                mDNS_Lock(m);

                // To not read the keychain twice: when BTMM is enabled, changes happen to the keychain
                // then the BTMM DynStore dictionary, so delay reading the keychain for a second.
                // NetworkChanged() will reset the keychain timer to fire immediately when the DynStore changes.
                //
                // In the "fixup" case where the BTMM DNS servers aren't accepting the key mDNSResponder has,
                // the DynStore dictionary won't change (because the BTMM zone won't change).  In that case,
                // a one second delay is ok, as we'll still converge to correctness, and there's no race
                // condition between the RegistrationDomain and the DomainAuthInfo.
                //
                // Lastly, non-BTMM WAB cases can use the keychain but not the DynStore, so we need to set
                // the timer here, as it will not get set by NetworkChanged().
                SetKeyChainTimer(m, mDNSPlatformOneSecond);

                mDNS_Unlock(m);
                KQueueUnlock(m, "KeychainChanged");
            }
        }
        CFRelease(skc);
    }

    return 0;
}
#endif

mDNSlocal void PowerOn(mDNS *const m)
{
    mDNSCoreMachineSleep(m, false);     // Will set m->SleepState = SleepState_Awake;
    if (m->p->WakeAtUTC)
    {
        long utc = mDNSPlatformUTC();
        mDNSPowerRequest(-1,-1);        // Need to explicitly clear any previous power requests -- they're not cleared automatically on wake
        if      (m->p->WakeAtUTC - utc > 30) LogSPS("PowerChanged PowerOn %d seconds early, assuming not maintenance wake",     m->p->WakeAtUTC - utc);
        else if (utc - m->p->WakeAtUTC > 30) LogSPS("PowerChanged PowerOn %d seconds late, assuming not maintenance wake",      utc - m->p->WakeAtUTC);
        else if (!strncasecmp(HINFO_HWstring, "K66AP", 5)) LogSPS("PowerChanged PowerOn %d seconds late, device is K66AP so not re-sleeping", utc - m->p->WakeAtUTC);
        else if (!strncasecmp(HINFO_HWstring, "J33AP", 5)) LogSPS("PowerChanged PowerOn %d seconds late, device is J33AP so not re-sleeping", utc - m->p->WakeAtUTC);
        else
        {
            LogSPS("PowerChanged: Waking for network maintenance operations %d seconds early; re-sleeping in 20 seconds", m->p->WakeAtUTC - utc);
            m->p->RequestReSleep = mDNS_TimeNow(m) + 20 * mDNSPlatformOneSecond;
        }
    }
}

mDNSlocal void PowerChanged(void *refcon, io_service_t service, natural_t messageType, void *messageArgument)
{
    mDNS *const m = (mDNS *const)refcon;
    KQueueLock(m);
    (void)service;    // Parameter not used
    debugf("PowerChanged %X %lX", messageType, messageArgument);

    // Make sure our m->SystemWakeOnLANEnabled value correctly reflects the current system setting
    m->SystemWakeOnLANEnabled = SystemWakeForNetworkAccess();

    switch(messageType)
    {
    case kIOMessageCanSystemPowerOff:       LogSPS("PowerChanged kIOMessageCanSystemPowerOff     (no action)"); break;          // E0000240
    case kIOMessageSystemWillPowerOff:      LogSPS("PowerChanged kIOMessageSystemWillPowerOff");                                // E0000250
        mDNSCoreMachineSleep(m, true);
        if (m->SleepState == SleepState_Sleeping) mDNSMacOSXNetworkChanged(m);
        break;
    case kIOMessageSystemWillNotPowerOff:   LogSPS("PowerChanged kIOMessageSystemWillNotPowerOff (no action)"); break;          // E0000260
    case kIOMessageCanSystemSleep:          LogSPS("PowerChanged kIOMessageCanSystemSleep        (no action)"); break;          // E0000270
    case kIOMessageSystemWillSleep:         LogSPS("PowerChanged kIOMessageSystemWillSleep");                                   // E0000280
        mDNSCoreMachineSleep(m, true);
        break;
    case kIOMessageSystemWillNotSleep:      LogSPS("PowerChanged kIOMessageSystemWillNotSleep    (no action)"); break;          // E0000290
    case kIOMessageSystemHasPoweredOn:      LogSPS("PowerChanged kIOMessageSystemHasPoweredOn");                                // E0000300
        // If still sleeping (didn't get 'WillPowerOn' message for some reason?) wake now
        if (m->SleepState)
        {
            LogMsg("PowerChanged kIOMessageSystemHasPoweredOn: ERROR m->SleepState %d", m->SleepState);
            PowerOn(m);
        }
        // Just to be safe, schedule a mDNSMacOSXNetworkChanged(), in case we never received
        // the System Configuration Framework "network changed" event that we expect
        // to receive some time shortly after the kIOMessageSystemWillPowerOn message
        mDNS_Lock(m);
        if (!m->p->NetworkChanged ||
            m->p->NetworkChanged - NonZeroTime(m->timenow + mDNSPlatformOneSecond * 2) < 0)
            m->p->NetworkChanged = NonZeroTime(m->timenow + mDNSPlatformOneSecond * 2);
        mDNS_Unlock(m);

        break;
    case kIOMessageSystemWillRestart:       LogSPS("PowerChanged kIOMessageSystemWillRestart     (no action)"); break;          // E0000310
    case kIOMessageSystemWillPowerOn:       LogSPS("PowerChanged kIOMessageSystemWillPowerOn");                                 // E0000320

        // On Leopard and earlier, on wake from sleep, instead of reporting link state down, Apple
        // Ethernet drivers report "hardware incapable of detecting link state", which the kernel
        // interprets as "should assume we have networking", which results in the first 4-5 seconds
        // of packets vanishing into a black hole. To work around this, on wake from sleep,
        // we block for five seconds to let Ethernet come up, and then resume normal operation.
        if (OSXVers && OSXVers < OSXVers_10_6_SnowLeopard)
        {
            sleep(5);
            LogMsg("Running on Mac OS X version 10.%d earlier than 10.6; "
                   "PowerChanged did sleep(5) to wait for Ethernet hardware", OSXVers - OSXVers_Base);
        }

        // Make sure our interface list is cleared to the empty state, then tell mDNSCore to wake
        if (m->SleepState != SleepState_Sleeping)
        {
            LogMsg("kIOMessageSystemWillPowerOn: ERROR m->SleepState %d", m->SleepState);
            m->SleepState = SleepState_Sleeping;
            mDNSMacOSXNetworkChanged(m);
        }
        PowerOn(m);
        break;
    default:                                LogSPS("PowerChanged unknown message %X", messageType); break;
    }

    if (messageType == kIOMessageSystemWillSleep) m->p->SleepCookie = (long)messageArgument;
    else IOAllowPowerChange(m->p->PowerConnection, (long)messageArgument);

    KQueueUnlock(m, "PowerChanged Sleep/Wake");
}

// iPhone OS doesn't currently have SnowLeopard's IO Power Management
// but it does define kIOPMAcknowledgmentOptionSystemCapabilityRequirements
#if defined(kIOPMAcknowledgmentOptionSystemCapabilityRequirements) && !TARGET_OS_EMBEDDED
mDNSlocal void SnowLeopardPowerChanged(void *refcon, IOPMConnection connection, IOPMConnectionMessageToken token, IOPMSystemPowerStateCapabilities eventDescriptor)
{
    mDNS *const m = (mDNS *const)refcon;
    KQueueLock(m);
    LogSPS("SnowLeopardPowerChanged %X %X %X%s%s%s%s%s",
           connection, token, eventDescriptor,
           eventDescriptor & kIOPMSystemPowerStateCapabilityCPU     ? " CPU"     : "",
           eventDescriptor & kIOPMSystemPowerStateCapabilityVideo   ? " Video"   : "",
           eventDescriptor & kIOPMSystemPowerStateCapabilityAudio   ? " Audio"   : "",
           eventDescriptor & kIOPMSystemPowerStateCapabilityNetwork ? " Network" : "",
           eventDescriptor & kIOPMSystemPowerStateCapabilityDisk    ? " Disk"    : "");

    // Make sure our m->SystemWakeOnLANEnabled value correctly reflects the current system setting
    m->SystemWakeOnLANEnabled = SystemWakeForNetworkAccess();

    if (eventDescriptor & kIOPMSystemPowerStateCapabilityCPU)
    {
        // We might be in Sleeping or Transferring state. When we go from "wakeup" to "sleep" state, we don't
        // go directly to sleep state, but transfer in to the sleep state during which SleepState is set to
        // SleepState_Transferring. During that time, we might get another wakeup before we transition to Sleeping
        // state. In that case, we need to acknowledge the previous "sleep" before we acknowledge the wakeup.
        if (m->SleepLimit)
        {
            LogSPS("SnowLeopardPowerChanged: Waking up, Acking old Sleep, SleepLimit %d SleepState %d", m->SleepLimit, m->SleepState);
            IOPMConnectionAcknowledgeEvent(connection, m->p->SleepCookie);
            m->SleepLimit = 0;
        }
        LogSPS("SnowLeopardPowerChanged: Waking up, Acking Wakeup, SleepLimit %d SleepState %d", m->SleepLimit, m->SleepState);
        // If the network notifications have already come before we got the wakeup, we ignored them and
        // in case we get no more, we need to trigger one.
        mDNS_Lock(m);
        SetNetworkChanged(m, 2 * mDNSPlatformOneSecond);
        mDNS_Unlock(m);
        // CPU Waking. Note: Can get this message repeatedly, as other subsystems power up or down.
        if (m->SleepState != SleepState_Awake) PowerOn(m);
        IOPMConnectionAcknowledgeEvent(connection, token);
    }
    else
    {
        // CPU sleeping. Should not get this repeatedly -- once we're told that the CPU is halting
        // we should hear nothing more until we're told that the CPU has started executing again.
        if (m->SleepState) LogMsg("SnowLeopardPowerChanged: Sleep Error %X m->SleepState %d", eventDescriptor, m->SleepState);
        //sleep(5);
        //mDNSMacOSXNetworkChanged(m);
        mDNSCoreMachineSleep(m, true);
        //if (m->SleepState == SleepState_Sleeping) mDNSMacOSXNetworkChanged(m);
        m->p->SleepCookie = token;
    }

    KQueueUnlock(m, "SnowLeopardPowerChanged Sleep/Wake");
}
#endif

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - /etc/hosts support
#endif

// Implementation Notes
//
// As /etc/hosts file can be huge (1000s of entries - when this comment was written, the test file had about
// 23000 entries with about 4000 duplicates), we can't use a linked list to store these entries. So, we parse
// them into a hash table. The implementation need to be able to do the following things efficiently
//
// 1. Detect duplicates e.g., two entries with "1.2.3.4 foo"
// 2. Detect whether /etc/hosts has changed and what has changed since the last read from the disk
// 3. Ability to support multiple addresses per name e.g., "1.2.3.4 foo, 2.3.4.5 foo". To support this, we
//    need to be able set the RRSet of a resource record to the first one in the list and also update when
//    one of them go away. This is needed so that the core thinks that they are all part of the same RRSet and
//    not a duplicate
// 4. Don't maintain any local state about any records registered with the core to detect changes to /etc/hosts
//
// CFDictionary is not a suitable candidate because it does not support duplicates and even if we use a custom
// "hash" function to solve this, the others are hard to solve. Hence, we share the hash (AuthHash) implementation
// of the core layer which does all of the above very efficiently

#define ETCHOSTS_BUFSIZE    1024    // Buffer size to parse a single line in /etc/hosts

mDNSexport void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result)
{
    (void)m;  // unused
    (void)rr;
    (void)result;
    if (result == mStatus_MemFree)
    {
        LogInfo("FreeEtcHosts: %s", ARDisplayString(m, rr));
        freeL("etchosts", rr);
    }
}

// Returns true on success and false on failure
mDNSlocal mDNSBool mDNSMacOSXCreateEtcHostsEntry(mDNS *const m, const domainname *domain, const struct sockaddr *sa, const domainname *cname, char *ifname, AuthHash *auth)
{
    AuthRecord *rr;
    mDNSu32 slot;
    mDNSu32 namehash;
    AuthGroup *ag;
    mDNSInterfaceID InterfaceID = mDNSInterface_LocalOnly;
    mDNSu16 rrtype;

    if (!domain)
    {
        LogMsg("mDNSMacOSXCreateEtcHostsEntry: ERROR!! name NULL");
        return mDNSfalse;
    }
    if (!sa && !cname)
    {
        LogMsg("mDNSMacOSXCreateEtcHostsEntry: ERROR!! sa and cname both NULL");
        return mDNSfalse;
    }

    if (sa && sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
    {
        LogMsg("mDNSMacOSXCreateEtcHostsEntry: ERROR!! sa with bad family %d", sa->sa_family);
        return mDNSfalse;
    }


    if (ifname)
    {
        mDNSu32 ifindex = if_nametoindex(ifname);
        if (!ifindex)
        {
            LogMsg("mDNSMacOSXCreateEtcHostsEntry: hosts entry %##s with invalid ifname %s", domain->c, ifname);
            return mDNSfalse;
        }
        InterfaceID = (mDNSInterfaceID)(uintptr_t)ifindex;
    }

    if (sa)
        rrtype = (sa->sa_family == AF_INET ? kDNSType_A : kDNSType_AAAA);
    else
        rrtype = kDNSType_CNAME;

    // Check for duplicates. See whether we parsed an entry before like this ?
    slot = AuthHashSlot(domain);
    namehash = DomainNameHashValue(domain);
    ag = AuthGroupForName(auth, slot, namehash, domain);
    if (ag)
    {
        rr = ag->members;
        while (rr)
        {
            if (rr->resrec.rrtype == rrtype)
            {
                if (rrtype == kDNSType_A)
                {
                    mDNSv4Addr ip;
                    ip.NotAnInteger = ((struct sockaddr_in*)sa)->sin_addr.s_addr;
                    if (mDNSSameIPv4Address(rr->resrec.rdata->u.ipv4, ip))
                    {
                        LogInfo("mDNSMacOSXCreateEtcHostsEntry: Same IPv4 address for name %##s", domain->c);
                        return mDNSfalse;
                    }
                }
                else if (rrtype == kDNSType_AAAA)
                {
                    mDNSv6Addr ip6;
                    ip6.l[0] = ((struct sockaddr_in6*)sa)->sin6_addr.__u6_addr.__u6_addr32[0];
                    ip6.l[1] = ((struct sockaddr_in6*)sa)->sin6_addr.__u6_addr.__u6_addr32[1];
                    ip6.l[2] = ((struct sockaddr_in6*)sa)->sin6_addr.__u6_addr.__u6_addr32[2];
                    ip6.l[3] = ((struct sockaddr_in6*)sa)->sin6_addr.__u6_addr.__u6_addr32[3];
                    if (mDNSSameIPv6Address(rr->resrec.rdata->u.ipv6, ip6))
                    {
                        LogInfo("mDNSMacOSXCreateEtcHostsEntry: Same IPv6 address for name %##s", domain->c);
                        return mDNSfalse;
                    }
                }
                else if (rrtype == kDNSType_CNAME)
                {
                    if (SameDomainName(&rr->resrec.rdata->u.name, cname))
                    {
                        LogInfo("mDNSMacOSXCreateEtcHostsEntry: Same cname %##s for name %##s", cname->c, domain->c);
                        return mDNSfalse;
                    }
                }
            }
            rr = rr->next;
        }
    }
    rr= mallocL("etchosts", sizeof(*rr));
    if (rr == NULL) return mDNSfalse;
    mDNSPlatformMemZero(rr, sizeof(*rr));
    mDNS_SetupResourceRecord(rr, NULL, InterfaceID, rrtype, 1, kDNSRecordTypeKnownUnique, AuthRecordLocalOnly, FreeEtcHosts, NULL);
    AssignDomainName(&rr->namestorage, domain);

    if (sa)
    {
        rr->resrec.rdlength = sa->sa_family == AF_INET ? sizeof(mDNSv4Addr) : sizeof(mDNSv6Addr);
        if (sa->sa_family == AF_INET)
            rr->resrec.rdata->u.ipv4.NotAnInteger = ((struct sockaddr_in*)sa)->sin_addr.s_addr;
        else
        {
            rr->resrec.rdata->u.ipv6.l[0] = ((struct sockaddr_in6*)sa)->sin6_addr.__u6_addr.__u6_addr32[0];
            rr->resrec.rdata->u.ipv6.l[1] = ((struct sockaddr_in6*)sa)->sin6_addr.__u6_addr.__u6_addr32[1];
            rr->resrec.rdata->u.ipv6.l[2] = ((struct sockaddr_in6*)sa)->sin6_addr.__u6_addr.__u6_addr32[2];
            rr->resrec.rdata->u.ipv6.l[3] = ((struct sockaddr_in6*)sa)->sin6_addr.__u6_addr.__u6_addr32[3];
        }
    }
    else
    {
        rr->resrec.rdlength = DomainNameLength(cname);
        rr->resrec.rdata->u.name.c[0] = 0;
        AssignDomainName(&rr->resrec.rdata->u.name, cname);
    }
    rr->resrec.namehash = DomainNameHashValue(rr->resrec.name);
    SetNewRData(&rr->resrec, mDNSNULL, 0);  // Sets rr->rdatahash for us
    LogInfo("mDNSMacOSXCreateEtcHostsEntry: Adding resource record %s", ARDisplayString(m, rr));
    InsertAuthRecord(m, auth, rr);
    return mDNStrue;
}

mDNSlocal int EtcHostsParseOneName(int start, int length, char *buffer, char **name)
{
    int i;

    *name = NULL;
    for (i = start; i < length; i++)
    {
        if (buffer[i] == '#')
            return -1;
        if (buffer[i] != ' ' && buffer[i] != ',' && buffer[i] != '\t')
        {
            *name = &buffer[i];

            // Found the start of a name, find the end and null terminate
            for (i++; i < length; i++)
            {
                if (buffer[i] == ' ' || buffer[i] == ',' || buffer[i] == '\t')
                {
                    buffer[i] = 0;
                    break;
                }
            }
            return i;
        }
    }
    return -1;
}

mDNSlocal void mDNSMacOSXParseEtcHostsLine(mDNS *const m, char *buffer, ssize_t length, AuthHash *auth)
{
    int i;
    int ifStart = 0;
    char *ifname = NULL;
    domainname name1d;
    domainname name2d;
    char *name1;
    char *name2;
    int aliasIndex;

    //Ignore leading whitespaces and tabs
    while (*buffer == ' ' || *buffer == '\t')
    {
        buffer++;
        length--;
    }

    // Find the end of the address string
    for (i = 0; i < length; i++)
    {
        if (buffer[i] == ' ' || buffer[i] == ',' || buffer[i] == '\t' || buffer[i] == '%')
        {
            if (buffer[i] == '%')
                ifStart = i + 1;
            buffer[i] = 0;
            break;
        }
    }

    // Convert the address string to an address
    struct addrinfo hints;
    bzero(&hints, sizeof(hints));
    hints.ai_flags = AI_NUMERICHOST;
    struct addrinfo *gairesults = NULL;
    if (getaddrinfo(buffer, NULL, &hints, &gairesults) != 0)
    {
        LogInfo("mDNSMacOSXParseEtcHostsLine: getaddrinfo returning null");
        return;
    }

    if (ifStart)
    {
        // Parse the interface
        ifname = &buffer[ifStart];
        for (i = ifStart + 1; i < length; i++)
        {
            if (buffer[i] == ' ' || buffer[i] == ',' || buffer[i] == '\t')
            {
                buffer[i] = 0;
                break;
            }
        }
    }

    i = EtcHostsParseOneName(i + 1, length, buffer, &name1);
    if (i == length)
    {
        // Common case (no aliases) : The entry is of the form "1.2.3.4 somehost" with no trailing white spaces/tabs etc.
        if (!MakeDomainNameFromDNSNameString(&name1d, name1))
        {
            LogMsg("mDNSMacOSXParseEtcHostsLine: ERROR!! cannot convert to domain name %s", name1);
            freeaddrinfo(gairesults);
            return;
        }
        mDNSMacOSXCreateEtcHostsEntry(m, &name1d, gairesults->ai_addr, mDNSNULL, ifname, auth);
    }
    else if (i != -1)
    {
        domainname first;
        // We might have some extra white spaces at the end for the common case of "1.2.3.4 somehost".
        // When we parse again below, EtchHostsParseOneName would return -1 and we will end up
        // doing the right thing.
        if (!MakeDomainNameFromDNSNameString(&first, name1))
        {
            LogMsg("mDNSMacOSXParseEtcHostsLine: ERROR!! cannot convert to domain name %s", name1);
            freeaddrinfo(gairesults);
            return;
        }
        // If the /etc/hosts has an entry like this
        //
        // 1.2.3.4 sun star bright
        //
        // star and bright are aliases (gethostbyname h_alias should point to these) and sun is the canonical
        // name (getaddrinfo ai_cannonname and gethostbyname h_name points to "sun")
        //
        // To achieve this, we need to add the entry like this:
        //
        // star CNAME bright
        // bright CNAME sun
        // sun A 1.2.3.4
        //
        // We store the first name we parsed in "first". Then we parse additional names adding CNAME records
        // till we reach the end. When we reach the end, we wrap around and add one final CNAME with the last
        // entry and the first entry. Finally, we add the Address (A/AAAA) record.
        aliasIndex = 0;
        while (i <= length)
        {
            // Parse a name. If there are no names, we need to know whether we
            // parsed CNAMEs before or not. If we parsed CNAMEs before, then we
            // add a CNAME with the last name and the first name. Otherwise, this
            // is same as the common case above where the line has just one name
            // but with trailing white spaces.
            i = EtcHostsParseOneName(i + 1, length, buffer, &name2);
            if (name2)
            {
                if (!MakeDomainNameFromDNSNameString(&name2d, name2))
                {
                    LogMsg("mDNSMacOSXParseEtcHostsLine: ERROR!! cannot convert to domain name %s", name2);
                    freeaddrinfo(gairesults);
                    return;
                }
                aliasIndex++;
            }
            else if (!aliasIndex)
            {
                // We have never parsed any aliases. This case happens if there
                // is just one name and some extra white spaces at the end.
                LogInfo("mDNSMacOSXParseEtcHostsLine: White space at the end of %##s", first.c);
                break;
            }
            else
            {
                // We have parsed at least one alias before and we reached the end of the line.
                // Setup a CNAME for the last name with "first" name as its RDATA
                name2d.c[0] = 0;
                AssignDomainName(&name2d, &first);
            }

            // Don't add a CNAME for the first alias we parse (see the example above).
            // As we parse more, we might discover that there are no more aliases, in
            // which case we would have set "name2d" to "first" above. We need to add
            // the CNAME in that case.

            if (aliasIndex > 1 || SameDomainName(&name2d, &first))
            {
                // Ignore if it points to itself
                if (!SameDomainName(&name1d, &name2d))
                {
                    if (!mDNSMacOSXCreateEtcHostsEntry(m, &name1d, mDNSNULL, &name2d, ifname, auth))
                    {
                        freeaddrinfo(gairesults);
                        return;
                    }
                }
                else
                    LogMsg("mDNSMacOSXParseEtcHostsLine: Ignoring entry with same names name1 %##s, name2 %##s", name1d.c, name2d.c);
            }

            // If we have already wrapped around, we just need to add the A/AAAA record alone
            // which is done below
            if (SameDomainName(&name2d, &first)) break;

            // Remember the current name so that we can set the CNAME record if we parse one
            // more name
            name1d.c[0] = 0;
            AssignDomainName(&name1d, &name2d);
        }
        // Added all the CNAMEs if any, add the "A/AAAA" record
        mDNSMacOSXCreateEtcHostsEntry(m, &first, gairesults->ai_addr, mDNSNULL, ifname, auth);
    }
    freeaddrinfo(gairesults);
}

mDNSlocal void mDNSMacOSXParseEtcHosts(mDNS *const m, int fd, AuthHash *auth)
{
    mDNSBool good;
    char buf[ETCHOSTS_BUFSIZE];
    ssize_t len;
    FILE *fp;

    if (fd == -1) { LogInfo("mDNSMacOSXParseEtcHosts: fd is -1"); return; }

    fp = fopen("/etc/hosts", "r");
    if (!fp) { LogInfo("mDNSMacOSXParseEtcHosts: fp is NULL"); return; }

    while (1)
    {
        good = (fgets(buf, ETCHOSTS_BUFSIZE, fp) != NULL);
        if (!good) break;

        // skip comment and empty lines
        if (buf[0] == '#' || buf[0] == '\r' || buf[0] == '\n')
            continue;

        len = strlen(buf);
        if (!len) break;    // sanity check
        //Check for end of line code(mostly only \n but pre-OS X Macs could have only \r)
        if (buf[len - 1] == '\r' || buf[len - 1] == '\n')
        {
            buf[len - 1] = '\0';
            len = len - 1;
        }
        // fgets always null terminates and hence even if we have no
        // newline at the end, it is null terminated. The callee
        // (mDNSMacOSXParseEtcHostsLine) expects the length to be such that
        // buf[length] is zero and hence we decrement len to reflect that.
        if (len)
        {
            //Additional check when end of line code is 2 chars ie\r\n(DOS, other old OSes)
            //here we need to check for just \r but taking extra caution.
            if (buf[len - 1] == '\r' || buf[len - 1] == '\n')
            {
                buf[len - 1] = '\0';
                len = len - 1;
            }
        }
        if (!len) //Sanity Check: len should never be zero
        {
            LogMsg("mDNSMacOSXParseEtcHosts: Length is zero!");
            continue;
        }
        mDNSMacOSXParseEtcHostsLine(m, buf, len, auth);
    }
    fclose(fp);
}

mDNSlocal void mDNSMacOSXUpdateEtcHosts(mDNS *const m);

mDNSlocal int mDNSMacOSXGetEtcHostsFD(mDNS *const m)
{
#ifdef __DISPATCH_GROUP__
    // Can't do this stuff to be notified of changes in /etc/hosts if we don't have libdispatch
    static dispatch_queue_t etcq     = 0;
    static dispatch_source_t etcsrc   = 0;
    static dispatch_source_t hostssrc = 0;

    // First time through? just schedule ourselves on the main queue and we'll do the work later
    if (!etcq)
    {
        etcq = dispatch_get_main_queue();
        if (etcq)
        {
            // Do this work on the queue, not here - solves potential synchronization issues
            dispatch_async(etcq, ^{mDNSMacOSXUpdateEtcHosts(m);});
        }
        return -1;
    }

    if (hostssrc) return dispatch_source_get_handle(hostssrc);
#endif

    int fd = open("/etc/hosts", O_RDONLY);

#ifdef __DISPATCH_GROUP__
    // Can't do this stuff to be notified of changes in /etc/hosts if we don't have libdispatch
    if (fd == -1)
    {
        // If the open failed and we're already watching /etc, we're done
        if (etcsrc) { LogInfo("mDNSMacOSXGetEtcHostsFD: Returning etcfd because no etchosts"); return fd; }

        // we aren't watching /etc, we should be
        fd = open("/etc", O_RDONLY);
        if (fd == -1) { LogInfo("mDNSMacOSXGetEtcHostsFD: etc does not exist"); return -1; }
        etcsrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fd, DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_RENAME, etcq);
        if (etcsrc == NULL)
        {
            close(fd);
            return -1;
        }
        dispatch_source_set_event_handler(etcsrc,
                                          ^{
                                              u_int32_t flags = dispatch_source_get_data(etcsrc);
                                              LogMsg("mDNSMacOSXGetEtcHostsFD: /etc changed 0x%x", flags);
                                              if ((flags & (DISPATCH_VNODE_DELETE | DISPATCH_VNODE_RENAME)) != 0)
                                              {
                                                  dispatch_source_cancel(etcsrc);
                                                  dispatch_release(etcsrc);
                                                  etcsrc = NULL;
                                                  dispatch_async(etcq, ^{mDNSMacOSXUpdateEtcHosts(m);});
                                                  return;
                                              }
                                              if ((flags & DISPATCH_VNODE_WRITE) != 0 && hostssrc == NULL)
                                              {
                                                  mDNSMacOSXUpdateEtcHosts(m);
                                              }
                                          });
        dispatch_source_set_cancel_handler(etcsrc, ^{close(fd);});
        dispatch_resume(etcsrc);

        // Try and open /etc/hosts once more now that we're watching /etc, in case we missed the creation
        fd = open("/etc/hosts", O_RDONLY | O_EVTONLY);
        if (fd == -1) { LogMsg("mDNSMacOSXGetEtcHostsFD etc hosts does not exist, watching etc"); return -1; }
    }

    // create a dispatch source to watch for changes to hosts file
    hostssrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fd,
                                      (DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_RENAME |
                                       DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_EXTEND | DISPATCH_VNODE_LINK | DISPATCH_VNODE_REVOKE), etcq);
    if (hostssrc == NULL)
    {
        close(fd);
        return -1;
    }
    dispatch_source_set_event_handler(hostssrc,
                                      ^{
                                          u_int32_t flags = dispatch_source_get_data(hostssrc);
                                          LogInfo("mDNSMacOSXGetEtcHostsFD: /etc/hosts changed 0x%x", flags);
                                          if ((flags & (DISPATCH_VNODE_DELETE | DISPATCH_VNODE_RENAME)) != 0)
                                          {
                                              dispatch_source_cancel(hostssrc);
                                              dispatch_release(hostssrc);
                                              hostssrc = NULL;
                                              // Bug in LibDispatch: wait a second before scheduling the block. If we schedule
                                              // the block immediately, we try to open the file and the file may not exist and may
                                              // fail to get a notification in the future. When the file does not exist and
                                              // we start to monitor the directory, on "dispatch_resume" of that source, there
                                              // is no guarantee that the file creation will be notified always because when
                                              // the dispatch_resume returns, the kevent manager may not have registered the
                                              // kevent yet but the file may have been created
                                              usleep(1000000);
                                              dispatch_async(etcq, ^{mDNSMacOSXUpdateEtcHosts(m);});
                                              return;
                                          }
                                          if ((flags & DISPATCH_VNODE_WRITE) != 0)
                                          {
                                              mDNSMacOSXUpdateEtcHosts(m);
                                          }
                                      });
    dispatch_source_set_cancel_handler(hostssrc, ^{LogInfo("mDNSMacOSXGetEtcHostsFD: Closing etchosts fd %d", fd); close(fd);});
    dispatch_resume(hostssrc);

    // Cleanup /etc source, no need to watch it if we already have /etc/hosts
    if (etcsrc)
    {
        dispatch_source_cancel(etcsrc);
        dispatch_release(etcsrc);
        etcsrc = NULL;
    }

    LogInfo("mDNSMacOSXGetEtcHostsFD: /etc/hosts being monitored, and not etc");
    return hostssrc ? (int)dispatch_source_get_handle(hostssrc) : -1;
#else
    (void)m;
    return fd;
#endif
}

// When /etc/hosts is modified, flush all the cache records as there may be local
// authoritative answers now
mDNSlocal void FlushAllCacheRecords(mDNS *const m)
{
    CacheRecord *cr;
    mDNSu32 slot;
    CacheGroup *cg;

    FORALL_CACHERECORDS(slot, cg, cr)
    {
        // Skip multicast.
        if (cr->resrec.InterfaceID) continue;

        // If a resource record can answer A or AAAA, they need to be flushed so that we will
        // never used to deliver an ADD or RMV
        if (RRTypeAnswersQuestionType(&cr->resrec, kDNSType_A) ||
            RRTypeAnswersQuestionType(&cr->resrec, kDNSType_AAAA))
        {
            LogInfo("FlushAllCacheRecords: Purging Resourcerecord %s", CRDisplayString(m, cr));
            mDNS_PurgeCacheResourceRecord(m, cr);
        }
    }
}

// Add new entries to the core. If justCheck is set, this function does not add, just returns true
mDNSlocal mDNSBool EtcHostsAddNewEntries(mDNS *const m, AuthHash *newhosts, mDNSBool justCheck)
{
    AuthGroup *ag;
    mDNSu32 slot;
    AuthRecord *rr, *primary, *rrnext;
    for (slot = 0; slot < AUTH_HASH_SLOTS; slot++)
        for (ag = newhosts->rrauth_hash[slot]; ag; ag = ag->next)
        {
            primary = NULL;
            for (rr = ag->members; rr; rr = rrnext)
            {
                rrnext = rr->next;
                AuthGroup *ag1;
                AuthRecord *rr1;
                mDNSBool found = mDNSfalse;
                ag1 = AuthGroupForRecord(&m->rrauth, slot, &rr->resrec);
                if (ag1 && ag1->members)
                {
                    if (!primary) primary = ag1->members;
                    rr1 = ag1->members;
                    while (rr1)
                    {
                        // We are not using InterfaceID in checking for duplicates. This means,
                        // if there are two addresses for a given name e.g., fe80::1%en0 and
                        // fe80::1%en1, we only add the first one. It is not clear whether
                        // this is a common case. To fix this, we also need to modify
                        // mDNS_Register_internal in how it handles duplicates. If it becomes a
                        // common case, we will fix it then.
                        if (IdenticalResourceRecord(&rr1->resrec, &rr->resrec))
                        {
                            LogInfo("EtcHostsAddNewEntries: Skipping, not adding %s", ARDisplayString(m, rr1));
                            found = mDNStrue;
                            break;
                        }
                        rr1 = rr1->next;
                    }
                }
                if (!found)
                {
                    if (justCheck)
                    {
                        LogInfo("EtcHostsAddNewEntries: Entry %s not registered with core yet", ARDisplayString(m, rr));
                        return mDNStrue;
                    }
                    RemoveAuthRecord(m, newhosts, rr);
                    // if there is no primary, point to self
                    rr->RRSet = (primary ? primary : rr);
                    rr->next = NULL;
                    LogInfo("EtcHostsAddNewEntries: Adding %s", ARDisplayString(m, rr));
                    if (mDNS_Register_internal(m, rr) != mStatus_NoError)
                        LogMsg("EtcHostsAddNewEntries: mDNS_Register failed for %s", ARDisplayString(m, rr));
                }
            }
        }
    return mDNSfalse;
}

// Delete entries from the core that are no longer needed. If justCheck is set, this function
// does not delete, just returns true
mDNSlocal mDNSBool EtcHostsDeleteOldEntries(mDNS *const m, AuthHash *newhosts, mDNSBool justCheck)
{
    AuthGroup *ag;
    mDNSu32 slot;
    AuthRecord *rr, *primary, *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)
            {
                mDNSBool found = mDNSfalse;
                AuthGroup *ag1;
                AuthRecord *rr1;
                rrnext = rr->next;
                if (rr->RecordCallback != FreeEtcHosts) continue;
                ag1 = AuthGroupForRecord(newhosts, slot, &rr->resrec);
                if (ag1)
                {
                    primary = rr1 = ag1->members;
                    while (rr1)
                    {
                        if (IdenticalResourceRecord(&rr1->resrec, &rr->resrec))
                        {
                            LogInfo("EtcHostsDeleteOldEntries: Old record %s found in new, skipping", ARDisplayString(m, rr));
                            found = mDNStrue;
                            break;
                        }
                        rr1 = rr1->next;
                    }
                }
                // there is no corresponding record in newhosts for the same name. This means
                // we should delete this from the core.
                if (!found)
                {
                    if (justCheck)
                    {
                        LogInfo("EtcHostsDeleteOldEntries: Record %s not found in new, deleting", ARDisplayString(m, rr));
                        return mDNStrue;
                    }
                    // if primary is going away, make sure that the rest of the records
                    // point to the new primary
                    if (rr == ag->members)
                    {
                        AuthRecord *new_primary = rr->next;
                        AuthRecord *r = new_primary;
                        while (r)
                        {
                            if (r->RRSet == rr)
                            {
                                LogInfo("EtcHostsDeleteOldEntries: Updating Resource Record %s to primary", ARDisplayString(m, r));
                                r->RRSet = new_primary;
                            }
                            else LogMsg("EtcHostsDeleteOldEntries: ERROR!! Resource Record %s not pointing to primary %##s", ARDisplayString(m, r), r->resrec.name);
                            r = r->next;
                        }
                    }
                    LogInfo("EtcHostsDeleteOldEntries: Deleting %s", ARDisplayString(m, rr));
                    mDNS_Deregister_internal(m, rr, mDNS_Dereg_normal);
                }
            }
    return mDNSfalse;
}

mDNSlocal void UpdateEtcHosts(mDNS *const m, void *context)
{
    AuthHash *newhosts = (AuthHash *)context;

    if (!m->mDNS_busy) LogMsg("UpdateEtcHosts: ERROR!! Lock not held");

    //Delete old entries from the core if they are not present in the newhosts
    EtcHostsDeleteOldEntries(m, newhosts, mDNSfalse);
    // Add the new entries to the core if not already present in the core
    EtcHostsAddNewEntries(m, newhosts, mDNSfalse);
}

mDNSlocal void FreeNewHosts(AuthHash *newhosts)
{
    mDNSu32 slot;
    AuthGroup *ag, *agnext;
    AuthRecord *rr, *rrnext;

    for (slot = 0; slot < AUTH_HASH_SLOTS; slot++)
        for (ag = newhosts->rrauth_hash[slot]; ag; ag = agnext)
        {
            agnext = ag->next;
            for (rr = ag->members; rr; rr = rrnext)
            {
                rrnext = rr->next;
                freeL("etchosts", rr);
            }
            freeL("AuthGroups", ag);
        }
}

mDNSlocal void mDNSMacOSXUpdateEtcHosts(mDNS *const m)
{
    AuthHash newhosts;

    // As we will be modifying the core, we can only have one thread running at
    // any point in time.
    KQueueLock(m);

    mDNSPlatformMemZero(&newhosts, sizeof(AuthHash));

    // Get the file desecriptor (will trigger us to start watching for changes)
    int fd = mDNSMacOSXGetEtcHostsFD(m);
    if (fd != -1)
    {
        LogInfo("mDNSMacOSXUpdateEtcHosts: Parsing /etc/hosts fd %d", fd);
        mDNSMacOSXParseEtcHosts(m, fd, &newhosts);
    }
    else LogInfo("mDNSMacOSXUpdateEtcHosts: /etc/hosts is not present");

    // Optimization: Detect whether /etc/hosts changed or not.
    //
    // 1. Check to see if there are any new entries. We do this by seeing whether any entries in
    //    newhosts is already registered with core.  If we find at least one entry that is not
    //    registered with core, then it means we have work to do.
    //
    // 2. Next, we check to see if any of the entries that are registered with core is not present
    //   in newhosts. If we find at least one entry that is not present, it means we have work to
    //   do.
    //
    // Note: We may not have to hold the lock right here as KQueueLock is held which prevents any
    // other thread from running. But mDNS_Lock is needed here as we will be traversing the core
    // data structure in EtcHostsDeleteOldEntries/NewEntries which might expect the lock to be held
    // in the future and this code does not have to change.
    mDNS_Lock(m);
    // Add the new entries to the core if not already present in the core
    if (!EtcHostsAddNewEntries(m, &newhosts, mDNStrue))
    {
        // No new entries to add, check to see if we need to delete any old entries from the
        // core if they are not present in the newhosts
        if (!EtcHostsDeleteOldEntries(m, &newhosts, mDNStrue))
        {
            LogInfo("mDNSMacOSXUpdateEtcHosts: No work");
            mDNS_Unlock(m);
            KQueueUnlock(m, "/etc/hosts changed");
            FreeNewHosts(&newhosts);
            return;
        }
    }

    // This will flush the cache, stop and start the query so that the queries
    // can look at the /etc/hosts again
    //
    // Notes:
    //
    // We can't delete and free the records here. We wait for the mDNSCoreRestartAddressQueries to
    // deliver RMV events. It has to be done in a deferred way because we can't deliver RMV
    // events for local records *before* the RMV events for cache records. mDNSCoreRestartAddressQueries
    // delivers these events in the right order and then calls us back to delete them.
    //
    // Similarly, we do a deferred Registration of the record because mDNSCoreRestartAddressQueries
    // is a common function that looks at all local auth records and delivers a RMV including
    // the records that we might add here. If we deliver a ADD here, it will get a RMV and then when
    // the query is restarted, it will get another ADD. To avoid this (ADD-RMV-ADD), we defer registering
    // the record until the RMVs are delivered in mDNSCoreRestartAddressQueries after which UpdateEtcHosts
    // is called back where we do the Registration of the record. This results in RMV followed by ADD which
    // looks normal.
    mDNSCoreRestartAddressQueries(m, mDNSfalse, FlushAllCacheRecords, UpdateEtcHosts, &newhosts);
    mDNS_Unlock(m);

    KQueueUnlock(m, "/etc/hosts changed");
    FreeNewHosts(&newhosts);
}

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - Initialization & Teardown
#endif

CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey;
CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey;
CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;

// Major version  6 is 10.2.x (Jaguar)
// Major version  7 is 10.3.x (Panther)
// Major version  8 is 10.4.x (Tiger)
// Major version  9 is 10.5.x (Leopard)
// Major version 10 is 10.6.x (SnowLeopard)
mDNSexport void mDNSMacOSXSystemBuildNumber(char *HINFO_SWstring)
{
    int major = 0, minor = 0;
    char letter = 0, prodname[256]="<Unknown>", prodvers[256]="<Unknown>", buildver[256]="<Unknown>";
    CFDictionaryRef vers = _CFCopySystemVersionDictionary();
    if (vers)
    {
        CFStringRef cfprodname = CFDictionaryGetValue(vers, _kCFSystemVersionProductNameKey);
        CFStringRef cfprodvers = CFDictionaryGetValue(vers, _kCFSystemVersionProductVersionKey);
        CFStringRef cfbuildver = CFDictionaryGetValue(vers, _kCFSystemVersionBuildVersionKey);
        if (cfprodname) CFStringGetCString(cfprodname, prodname, sizeof(prodname), kCFStringEncodingUTF8);
        if (cfprodvers) CFStringGetCString(cfprodvers, prodvers, sizeof(prodvers), kCFStringEncodingUTF8);
        if (cfbuildver && CFStringGetCString(cfbuildver, buildver, sizeof(buildver), kCFStringEncodingUTF8))
            sscanf(buildver, "%d%c%d", &major, &letter, &minor);
        CFRelease(vers);
    }
    if (!major) { major=8; LogMsg("Note: No Major Build Version number found; assuming 8"); }
    if (HINFO_SWstring) mDNS_snprintf(HINFO_SWstring, 256, "%s %s (%s), %s", prodname, prodvers, buildver, STRINGIFY(mDNSResponderVersion));
    //LogMsg("%s %s (%s), %d %c %d", prodname, prodvers, buildver, major, letter, minor);

    // If product name is "Mac OS X" (or similar) we set OSXVers, else we set iOSVers;
    if ((prodname[0] & 0xDF) == 'M') OSXVers = major;else iOSVers = major;
}

// Test to see if we're the first client running on UDP port 5353, by trying to bind to 5353 without using SO_REUSEPORT.
// If we fail, someone else got here first. That's not a big problem; we can share the port for multicast responses --
// we just need to be aware that we shouldn't expect to successfully receive unicast UDP responses.
mDNSlocal mDNSBool mDNSPlatformInit_CanReceiveUnicast(void)
{
    int err = -1;
    int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (s < 3)
        LogMsg("mDNSPlatformInit_CanReceiveUnicast: socket error %d errno %d (%s)", s, errno, strerror(errno));
    else
    {
        struct sockaddr_in s5353;
        s5353.sin_family      = AF_INET;
        s5353.sin_port        = MulticastDNSPort.NotAnInteger;
        s5353.sin_addr.s_addr = 0;
        err = bind(s, (struct sockaddr *)&s5353, sizeof(s5353));
        close(s);
    }

    if (err) LogMsg("No unicast UDP responses");
    else debugf("Unicast UDP responses okay");
    return(err == 0);
}

mDNSlocal void CreatePTRRecord(mDNS *const m, const domainname *domain)
{
    AuthRecord *rr;
    const domainname *pname = (domainname *)"\x9" "localhost";

    rr= mallocL("localhosts", sizeof(*rr));
    if (rr == NULL) return;
    mDNSPlatformMemZero(rr, sizeof(*rr));

    mDNS_SetupResourceRecord(rr, mDNSNULL, mDNSInterface_LocalOnly, kDNSType_PTR, kHostNameTTL, kDNSRecordTypeKnownUnique, AuthRecordLocalOnly, mDNSNULL, mDNSNULL);
    AssignDomainName(&rr->namestorage, domain);

    rr->resrec.rdlength = DomainNameLength(pname);
    rr->resrec.rdata->u.name.c[0] = 0;
    AssignDomainName(&rr->resrec.rdata->u.name, pname);

    rr->resrec.namehash = DomainNameHashValue(rr->resrec.name);
    SetNewRData(&rr->resrec, mDNSNULL, 0);  // Sets rr->rdatahash for us
    mDNS_Register(m, rr);
}

// Setup PTR records for 127.0.0.1 and ::1. This helps answering them locally rather than relying
// on the external DNS server to answer this. Sometimes, the DNS servers don't respond in a timely
// fashion and applications depending on this e.g., telnetd, times out after 30 seconds creating
// a bad user experience. For now, we specifically create only localhosts to handle radar://9354225
//
// Note: We could have set this up while parsing the entries in /etc/hosts. But this is kept separate
// intentionally to avoid adding to the complexity of code handling /etc/hosts.
mDNSlocal void SetupLocalHostRecords(mDNS *const m)
{
    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(m, &name);
    }
    else LogMsg("SetupLocalHostRecords: ERROR!! inet_pton AF_INET failed");

    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(m, &name);
    }
    else LogMsg("SetupLocalHostRecords: ERROR!! inet_pton AF_INET6 failed");
}

// Construction of Default Browse domain list (i.e. when clients pass NULL) is as follows:
// 1) query for b._dns-sd._udp.local on LocalOnly interface
//    (.local manually generated via explicit callback)
// 2) for each search domain (from prefs pane), query for b._dns-sd._udp.<searchdomain>.
// 3) for each result from (2), register LocalOnly PTR record b._dns-sd._udp.local. -> <result>
// 4) result above should generate a callback from question in (1).  result added to global list
// 5) global list delivered to client via GetSearchDomainList()
// 6) client calls to enumerate domains now go over LocalOnly interface
//    (!!!KRS may add outgoing interface in addition)

mDNSlocal mStatus mDNSPlatformInit_setup(mDNS *const m)
{
    mStatus err;
    m->p->CFRunLoop = CFRunLoopGetCurrent();

    char HINFO_SWstring[256] = "";
    mDNSMacOSXSystemBuildNumber(HINFO_SWstring);

    // In 10.4, mDNSResponder is launched very early in the boot process, while other subsystems are still in the process of starting up.
    // If we can't read the user's preferences, then we sleep a bit and try again, for up to five seconds before we give up.
    int i;
    for (i=0; i<100; i++)
    {
        domainlabel testlabel;
        testlabel.c[0] = 0;
        GetUserSpecifiedLocalHostName(&testlabel);
        if (testlabel.c[0]) break;
        usleep(50000);
    }

    m->hostlabel.c[0]        = 0;

    int get_model[2] = { CTL_HW, HW_MODEL };
    size_t len_model = sizeof(HINFO_HWstring_buffer);

    // Normal Apple model names are of the form "iPhone2,1", and
    // internal code names are strings containing no commas, e.g. "N88AP".
    // We used to ignore internal code names, but Apple now uses these internal code names
    // even in released shipping products, so we no longer ignore strings containing no commas.
//	if (sysctl(get_model, 2, HINFO_HWstring_buffer, &len_model, NULL, 0) == 0 && strchr(HINFO_HWstring_buffer, ','))
    if (sysctl(get_model, 2, HINFO_HWstring_buffer, &len_model, NULL, 0) == 0)
        HINFO_HWstring = HINFO_HWstring_buffer;

    // For names of the form "iPhone2,1" we use "iPhone" as the prefix for automatic name generation.
    // For names of the form "N88AP" containg no comma, we use the entire string.
    HINFO_HWstring_prefixlen = strchr(HINFO_HWstring_buffer, ',') ? strcspn(HINFO_HWstring, "0123456789") : strlen(HINFO_HWstring);

    if (OSXVers && OSXVers <= OSXVers_10_6_SnowLeopard) m->KnownBugs |= mDNS_KnownBug_LimitedIPv6;
    if (OSXVers && OSXVers >= OSXVers_10_6_SnowLeopard) m->KnownBugs |= mDNS_KnownBug_LossySyslog;
    if (mDNSPlatformInit_CanReceiveUnicast()) m->CanReceiveUnicastOn5353 = mDNStrue;

    mDNSu32 hlen = mDNSPlatformStrLen(HINFO_HWstring);
    mDNSu32 slen = mDNSPlatformStrLen(HINFO_SWstring);
    if (hlen + slen < 254)
    {
        m->HIHardware.c[0] = hlen;
        m->HISoftware.c[0] = slen;
        mDNSPlatformMemCopy(&m->HIHardware.c[1], HINFO_HWstring, hlen);
        mDNSPlatformMemCopy(&m->HISoftware.c[1], HINFO_SWstring, slen);
    }

    m->p->permanentsockets.port  = MulticastDNSPort;
    m->p->permanentsockets.m     = 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";
#ifndef NO_IPV6
    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";
#endif

    err = SetupSocket(&m->p->permanentsockets, MulticastDNSPort, AF_INET, mDNSNULL);
#ifndef NO_IPV6
    err = SetupSocket(&m->p->permanentsockets, MulticastDNSPort, AF_INET6, mDNSNULL);
#endif

    struct sockaddr_in s4;
    socklen_t n4 = sizeof(s4);
    if (getsockname(m->p->permanentsockets.sktv4, (struct sockaddr *)&s4, &n4) < 0) LogMsg("getsockname v4 error %d (%s)", errno, strerror(errno));
    else m->UnicastPort4.NotAnInteger = s4.sin_port;
#ifndef NO_IPV6
    if (m->p->permanentsockets.sktv6 >= 0)
    {
        struct sockaddr_in6 s6;
        socklen_t n6 = sizeof(s6);
        if (getsockname(m->p->permanentsockets.sktv6, (struct sockaddr *)&s6, &n6) < 0) LogMsg("getsockname v6 error %d (%s)", errno, strerror(errno));
        else m->UnicastPort6.NotAnInteger = s6.sin6_port;
    }
#endif

    m->p->InterfaceList      = mDNSNULL;
    m->p->userhostlabel.c[0] = 0;
    m->p->usernicelabel.c[0] = 0;
    m->p->prevoldnicelabel.c[0] = 0;
    m->p->prevnewnicelabel.c[0] = 0;
    m->p->prevoldhostlabel.c[0] = 0;
    m->p->prevnewhostlabel.c[0] = 0;
    m->p->NotifyUser         = 0;
    m->p->KeyChainTimer      = 0;
    m->p->WakeAtUTC          = 0;
    m->p->RequestReSleep     = 0;
#if APPLE_OSX_mDNSResponder
    uuid_generate(m->asl_uuid);
#endif

    m->AutoTunnelRelayAddr = zerov6Addr;

    NetworkChangedKey_IPv4         = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4);
    NetworkChangedKey_IPv6         = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv6);
    NetworkChangedKey_Hostnames    = SCDynamicStoreKeyCreateHostNames(NULL);
    NetworkChangedKey_Computername = SCDynamicStoreKeyCreateComputerName(NULL);
    NetworkChangedKey_DNS          = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetDNS);
    if (!NetworkChangedKey_IPv4 || !NetworkChangedKey_IPv6 || !NetworkChangedKey_Hostnames || !NetworkChangedKey_Computername || !NetworkChangedKey_DNS)
    { LogMsg("SCDynamicStore string setup failed"); return(mStatus_NoMemoryErr); }

    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();
    UpdateInterfaceList(m, utc);
    SetupActiveInterfaces(m, utc);

    // Explicitly ensure that our Keychain operations utilize the system domain.
#ifndef NO_SECURITYFRAMEWORK
    SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem);
#endif

    mDNS_Lock(m);
    SetDomainSecrets(m);
    SetLocalDomains();
    mDNS_Unlock(m);

#ifndef NO_SECURITYFRAMEWORK
    err = SecKeychainAddCallback(KeychainChanged, kSecAddEventMask|kSecDeleteEventMask|kSecUpdateEventMask, m);
    if (err) { LogMsg("mDNSPlatformInit_setup: SecKeychainAddCallback failed %d", err); return(err); }
#endif

#if !defined(kIOPMAcknowledgmentOptionSystemCapabilityRequirements) || TARGET_OS_EMBEDDED
    LogMsg("Note: Compiled without SnowLeopard Fine-Grained Power Management support");
#else
    IOPMConnection c;
    IOReturn iopmerr = IOPMConnectionCreate(CFSTR("mDNSResponder"), kIOPMSystemPowerStateCapabilityCPU, &c);
    if (iopmerr) LogMsg("IOPMConnectionCreate failed %d", iopmerr);
    else
    {
        iopmerr = IOPMConnectionSetNotification(c, m, SnowLeopardPowerChanged);
        if (iopmerr) LogMsg("IOPMConnectionSetNotification failed %d", iopmerr);
        else
        {
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
            IOPMConnectionSetDispatchQueue(c, dispatch_get_main_queue());
            LogInfo("IOPMConnectionSetDispatchQueue is now running");
#else
            iopmerr = IOPMConnectionScheduleWithRunLoop(c, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
            if (iopmerr) LogMsg("IOPMConnectionScheduleWithRunLoop failed %d", iopmerr);
            LogInfo("IOPMConnectionScheduleWithRunLoop is now running");
#endif /* MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM */
        }
    }
    m->p->IOPMConnection = iopmerr ? mDNSNULL : c;
    if (iopmerr) // If IOPMConnectionCreate unavailable or failed, proceed with old-style power notification code below
#endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
    {
        m->p->PowerConnection = IORegisterForSystemPower(m, &m->p->PowerPortRef, PowerChanged, &m->p->PowerNotifier);
        if (!m->p->PowerConnection) { LogMsg("mDNSPlatformInit_setup: IORegisterForSystemPower failed"); return(-1); }
        else
        {
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
            IONotificationPortSetDispatchQueue(m->p->PowerPortRef, dispatch_get_main_queue());
#else
            CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(m->p->PowerPortRef), kCFRunLoopDefaultMode);
#endif /* MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM */
        }
    }

#if APPLE_OSX_mDNSResponder
    // Note: We use SPMetricPortability > 35 to indicate a laptop of some kind
    // SPMetricPortability <= 35 means nominally a non-portable machine (i.e. Mac mini or better)
    // Apple TVs, AirPort base stations, and Time Capsules do not actually weigh 3kg, but we assign them
    // higher 'nominal' masses to indicate they should be treated as being relatively less portable than a laptop
    if      (!strncasecmp(HINFO_HWstring, "Xserve",       6)) { SPMetricPortability = 25 /* 30kg */; SPMetricMarginalPower = 84 /* 250W */; SPMetricTotalPower = 85 /* 300W */; }
    else if (!strncasecmp(HINFO_HWstring, "RackMac",      7)) { SPMetricPortability = 25 /* 30kg */; SPMetricMarginalPower = 84 /* 250W */; SPMetricTotalPower = 85 /* 300W */; }
    else if (!strncasecmp(HINFO_HWstring, "MacPro",       6)) { SPMetricPortability = 27 /* 20kg */; SPMetricMarginalPower = 84 /* 250W */; SPMetricTotalPower = 85 /* 300W */; }
    else if (!strncasecmp(HINFO_HWstring, "PowerMac",     8)) { SPMetricPortability = 27 /* 20kg */; SPMetricMarginalPower = 82 /* 160W */; SPMetricTotalPower = 83 /* 200W */; }
    else if (!strncasecmp(HINFO_HWstring, "iMac",         4)) { SPMetricPortability = 30 /* 10kg */; SPMetricMarginalPower = 77 /*  50W */; SPMetricTotalPower = 78 /*  60W */; }
    else if (!strncasecmp(HINFO_HWstring, "Macmini",      7)) { SPMetricPortability = 33 /*  5kg */; SPMetricMarginalPower = 73 /*  20W */; SPMetricTotalPower = 74 /*  25W */; }
    else if (!strncasecmp(HINFO_HWstring, "TimeCapsule", 11)) { SPMetricPortability = 34 /*  4kg */; SPMetricMarginalPower = 10 /*  ~0W */; SPMetricTotalPower = 70 /*  13W */; }
    else if (!strncasecmp(HINFO_HWstring, "AirPort",      7)) { SPMetricPortability = 35 /*  3kg */; SPMetricMarginalPower = 10 /*  ~0W */; SPMetricTotalPower = 70 /*  12W */; }
    else if (!strncasecmp(HINFO_HWstring, "AppleTV",      7)) { SPMetricPortability = 35 /*  3kg */; SPMetricMarginalPower = 10 /*  ~0W */; SPMetricTotalPower = 73 /*  20W */; }
    else if (!strncasecmp(HINFO_HWstring, "K66AP",        5)) { SPMetricPortability = 35 /*  3kg */; SPMetricMarginalPower = 60 /*   1W */; SPMetricTotalPower = 63 /*   2W */; }
    else if (!strncasecmp(HINFO_HWstring, "J33AP",        5)) { SPMetricPortability = 35 /*  3kg */; SPMetricMarginalPower = 60 /*   1W */; SPMetricTotalPower = 63 /*   2W */; }
    else if (!strncasecmp(HINFO_HWstring, "MacBook",      7)) { SPMetricPortability = 37 /*  2kg */; SPMetricMarginalPower = 71 /*  13W */; SPMetricTotalPower = 72 /*  15W */; }
    else if (!strncasecmp(HINFO_HWstring, "PowerBook",    9)) { SPMetricPortability = 37 /*  2kg */; SPMetricMarginalPower = 71 /*  13W */; SPMetricTotalPower = 72 /*  15W */; }
    LogSPS("HW_MODEL: %.*s (%s) Portability %d Marginal Power %d Total Power %d Features %d",
           HINFO_HWstring_prefixlen, HINFO_HWstring, HINFO_HWstring, SPMetricPortability, SPMetricMarginalPower, SPMetricTotalPower, SPMetricFeatures);
#endif // APPLE_OSX_mDNSResponder

#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
    // Currently this is not defined. SSL code will eventually fix this. If it becomes
    // critical, we will define this to workaround the bug in SSL.
#ifdef __SSL_NEEDS_SERIALIZATION__
    SSLqueue = dispatch_queue_create("com.apple.mDNSResponder.SSLQueue", NULL);
#else
    SSLqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
#endif
    if (SSLqueue == mDNSNULL) LogMsg("dispatch_queue_create: SSL queue NULL");
#endif
    mDNSMacOSXUpdateEtcHosts(m);
    SetupLocalHostRecords(m);
    m->TrustAnchors = mDNSNULL;
    return(mStatus_NoError);
}

mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
{
#if MDNS_NO_DNSINFO
    LogMsg("Note: Compiled without Apple-specific Split-DNS support");
#endif

    // Adding interfaces will use this flag, so set it now.
    m->DivertMulticastAdvertisements = !m->AdvertiseLocalAddresses;

#if APPLE_OSX_mDNSResponder
    m->SPSBrowseCallback = UpdateSPSStatus;
#endif // APPLE_OSX_mDNSResponder

    mStatus result = mDNSPlatformInit_setup(m);

    // We don't do asynchronous initialization on OS X, so by the time we get here the setup will already
    // have succeeded or failed -- so if it succeeded, we should just call mDNSCoreInitComplete() immediately
    if (result == mStatus_NoError)
    {
        mDNSCoreInitComplete(m, mStatus_NoError);

#if !NO_D2D
        // We only initialize if mDNSCore successfully initialized.
        if (D2DInitialize)
        {
            D2DStatus ds = D2DInitialize(m->p->CFRunLoop, xD2DServiceCallback, m) ;
            if (ds != kD2DSuccess)
                LogMsg("D2DInitialiize failed: %d", ds);
            else
                LogMsg("D2DInitialize succeeded");
        }
#endif // ! NO_D2D

    }
    result = DNSSECCryptoInit(m);
    return(result);
}

mDNSexport void mDNSPlatformClose(mDNS *const m)
{
    if (m->p->PowerConnection)
    {
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
        IONotificationPortSetDispatchQueue(m->p->PowerPortRef, NULL);
#else
        CFRunLoopRemoveSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(m->p->PowerPortRef), kCFRunLoopDefaultMode);
#endif
        // According to <http://developer.apple.com/qa/qa2004/qa1340.html>, a single call
        // to IORegisterForSystemPower creates *three* objects that need to be disposed individually:
        IODeregisterForSystemPower(&m->p->PowerNotifier);
        IOServiceClose            ( m->p->PowerConnection);
        IONotificationPortDestroy ( m->p->PowerPortRef);
        m->p->PowerConnection = 0;
    }

    if (m->p->Store)
    {
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
        if (!SCDynamicStoreSetDispatchQueue(m->p->Store, NULL))
            LogMsg("mDNSPlatformClose: SCDynamicStoreSetDispatchQueue failed");
#else
        CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m->p->StoreRLS, kCFRunLoopDefaultMode);
        CFRunLoopSourceInvalidate(m->p->StoreRLS);
        CFRelease(m->p->StoreRLS);
        m->p->StoreRLS = NULL;
#endif
        CFRelease(m->p->Store);
        m->p->Store    = NULL;
    }

    if (m->p->PMRLS)
    {
        CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m->p->PMRLS, kCFRunLoopDefaultMode);
        CFRunLoopSourceInvalidate(m->p->PMRLS);
        CFRelease(m->p->PMRLS);
        m->p->PMRLS = NULL;
    }

    if (m->p->SysEventNotifier >= 0) { close(m->p->SysEventNotifier); m->p->SysEventNotifier = -1; }

#if !NO_D2D
    if (D2DTerminate)
    {
        D2DStatus ds = D2DTerminate();
        if (ds != kD2DSuccess)
            LogMsg("D2DTerminate failed: %d", ds);
        else
            LogMsg("D2DTerminate succeeded");
    }
#endif // ! NO_D2D

    mDNSs32 utc = mDNSPlatformUTC();
    MarkAllInterfacesInactive(m, utc);
    ClearInactiveInterfaces(m, utc);
    CloseSocketSet(&m->p->permanentsockets);

#if APPLE_OSX_mDNSResponder
    // clean up tunnels
    while (m->TunnelClients)
    {
        ClientTunnel *cur = m->TunnelClients;
        LogInfo("mDNSPlatformClose: removing client tunnel %p %##s from list", cur, cur->dstname.c);
        if (cur->q.ThisQInterval >= 0) mDNS_StopQuery(m, &cur->q);
        AutoTunnelSetKeys(cur, mDNSfalse);
        m->TunnelClients = cur->next;
        freeL("ClientTunnel", cur);
    }

    if (AnonymousRacoonConfig)
    {
        AnonymousRacoonConfig = mDNSNULL;
        LogInfo("mDNSPlatformClose: Deconfiguring autotunnel");
        (void)mDNSConfigureServer(kmDNSDown, mDNSNULL, mDNSNULL);
    }
#endif // APPLE_OSX_mDNSResponder
}

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - General Platform Support Layer functions
#endif

mDNSexport mDNSu32 mDNSPlatformRandomNumber(void)
{
    return(arc4random());
}

mDNSexport mDNSs32 mDNSPlatformOneSecond = 1000;
mDNSexport mDNSu32 mDNSPlatformClockDivisor = 0;

mDNSexport mStatus mDNSPlatformTimeInit(void)
{
    // Notes: Typical values for mach_timebase_info:
    // tbi.numer = 1000 million
    // tbi.denom =   33 million
    // These are set such that (mach_absolute_time() * numer/denom) gives us nanoseconds;
    //          numer  / denom = nanoseconds per hardware clock tick (e.g. 30);
    //          denom  / numer = hardware clock ticks per nanosecond (e.g. 0.033)
    // (denom*1000000) / numer = hardware clock ticks per millisecond (e.g. 33333)
    // So: mach_absolute_time() / ((denom*1000000)/numer) = milliseconds
    //
    // Arithmetic notes:
    // tbi.denom is at least 1, and not more than 2^32-1.
    // Therefore (tbi.denom * 1000000) is at least one million, but cannot overflow a uint64_t.
    // tbi.denom is at least 1, and not more than 2^32-1.
    // Therefore clockdivisor should end up being a number roughly in the range 10^3 - 10^9.
    // If clockdivisor is less than 10^3 then that means that the native clock frequency is less than 1MHz,
    // which is unlikely on any current or future Macintosh.
    // If clockdivisor is greater than 10^9 then that means the native clock frequency is greater than 1000GHz.
    // When we ship Macs with clock frequencies above 1000GHz, we may have to update this code.
    struct mach_timebase_info tbi;
    kern_return_t result = mach_timebase_info(&tbi);
    if (result == KERN_SUCCESS) mDNSPlatformClockDivisor = ((uint64_t)tbi.denom * 1000000) / tbi.numer;
    return(result);
}

mDNSexport mDNSs32 mDNSPlatformRawTime(void)
{
    if (mDNSPlatformClockDivisor == 0) { LogMsg("mDNSPlatformRawTime called before mDNSPlatformTimeInit"); return(0); }

    static uint64_t last_mach_absolute_time = 0;
    //static uint64_t last_mach_absolute_time = 0x8000000000000000LL;	// Use this value for testing the alert display
    uint64_t this_mach_absolute_time = mach_absolute_time();
    if ((int64_t)this_mach_absolute_time - (int64_t)last_mach_absolute_time < 0)
    {
        LogMsg("mDNSPlatformRawTime: last_mach_absolute_time %08X%08X", last_mach_absolute_time);
        LogMsg("mDNSPlatformRawTime: this_mach_absolute_time %08X%08X", this_mach_absolute_time);
        // Update last_mach_absolute_time *before* calling NotifyOfElusiveBug()
        last_mach_absolute_time = this_mach_absolute_time;
        // Note: This bug happens all the time on 10.3
        NotifyOfElusiveBug("mach_absolute_time went backwards!",
                           "This error occurs from time to time, often on newly released hardware, "
                           "and usually the exact cause is different in each instance.\r\r"
                           "Please file a new Radar bug report with the title “mach_absolute_time went backwards” "
                           "and assign it to Radar Component “Kernel” Version “X”.");
    }
    last_mach_absolute_time = this_mach_absolute_time;

    return((mDNSs32)(this_mach_absolute_time / mDNSPlatformClockDivisor));
}

mDNSexport mDNSs32 mDNSPlatformUTC(void)
{
    return time(NULL);
}

// Locking is a no-op here, because we're single-threaded with a CFRunLoop, so we can never interrupt ourselves
mDNSexport void     mDNSPlatformLock   (const mDNS *const m) { (void)m; }
mDNSexport void     mDNSPlatformUnlock (const mDNS *const m) { (void)m; }
mDNSexport void     mDNSPlatformStrCopy(      void *dst, const void *src)              { strcpy((char *)dst, (char *)src); }
mDNSexport mDNSu32  mDNSPlatformStrLen (                 const void *src)              { return(strlen((char*)src)); }
mDNSexport void     mDNSPlatformMemCopy(      void *dst, const void *src, mDNSu32 len) { memcpy(dst, src, len); }
mDNSexport mDNSBool mDNSPlatformMemSame(const void *dst, const void *src, mDNSu32 len) { return(memcmp(dst, src, len) == 0); }
mDNSexport int      mDNSPlatformMemCmp(const void *dst, const void *src, mDNSu32 len) { return(memcmp(dst, src, len)); }
mDNSexport void     mDNSPlatformMemZero(      void *dst,                  mDNSu32 len) { memset(dst, 0, len); }
mDNSexport void     mDNSPlatformQsort  (      void *base, int nel, int width, int (*compar)(const void *, const void *))
{
    return (qsort(base, nel, width, compar));
}
#if !(APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING)
mDNSexport void *   mDNSPlatformMemAllocate(mDNSu32 len) { return(mallocL("mDNSPlatformMemAllocate", len)); }
#endif
mDNSexport void     mDNSPlatformMemFree    (void *mem)   { freeL("mDNSPlatformMemFree", mem); }

mDNSexport void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, const char *reason)
{
    if (allowSleep && m->p->IOPMAssertion)
    {
        LogInfo("%s Destroying NoIdleSleep power assertion", __FUNCTION__);
        IOPMAssertionRelease(m->p->IOPMAssertion);
        m->p->IOPMAssertion = 0;
    }
    else if (!allowSleep && m->p->IOPMAssertion == 0)
    {
#ifdef kIOPMAssertionTypeNoIdleSleep
        CFStringRef assertionName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s.%d %s"), getprogname(), getpid(), reason ? reason : "");
        IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, assertionName ? assertionName : CFSTR("mDNSResponder"), &m->p->IOPMAssertion);
        if (assertionName) CFRelease(assertionName);
        LogInfo("%s Creating NoIdleSleep power assertion", __FUNCTION__);
#endif
    }
}

mDNSexport void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration)
{
    mDNSu32 ifindex;

    // Sanity check
    ifindex = mDNSPlatformInterfaceIndexfromInterfaceID(m, InterfaceID, mDNStrue);
    if (ifindex <= 0)
    {
        LogMsg("mDNSPlatformSendWakeupPacket: ERROR!! Invalid InterfaceID %u", ifindex);
        return;
    }
    mDNSSendWakeupPacket(ifindex, EthAddr, IPAddr, iteration);
}

mDNSexport mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID)
{
    NetworkInterfaceInfoOSX *info;

    if (InterfaceID == mDNSInterface_P2P)
        return mDNStrue;

    if (   (InterfaceID == mDNSInterface_Any) 
        || (InterfaceID == mDNSInterfaceMark)
        || (InterfaceID == mDNSInterface_LocalOnly)
        || (InterfaceID == mDNSInterface_Unicast))
        return mDNSfalse;

    info = IfindexToInterfaceInfoOSX(&mDNSStorage, InterfaceID);
    if (info == NULL)
    {
        // this log message can print when operations are stopped on an interface that has gone away
        LogInfo("mDNSPlatformInterfaceIsD2D: Invalid interface index %d", InterfaceID);
        return mDNSfalse;
    }

    return (mDNSBool) info->D2DInterface;
}

// Filter records send over P2P (D2D) type interfaces
// Note that the terms P2P and D2D are used synonymously in the current code and comments.
mDNSexport mDNSBool mDNSPlatformValidRecordForInterface(AuthRecord *rr, const NetworkInterfaceInfo *intf)
{
    // For an explicit match to a valid interface ID, return true. 
    if (rr->resrec.InterfaceID == intf->InterfaceID)
        return mDNStrue;

    // Only filtering records for D2D type interfaces, return true for all other interface types.
    if (!mDNSPlatformInterfaceIsD2D(intf->InterfaceID))
        return mDNStrue;
    
    // If it's an AWDL interface the record must be explicitly marked to include AWDL.
    if (intf->InterfaceID == AWDLInterfaceID)
    {
        if (rr->ARType == AuthRecordAnyIncludeAWDL)
            return mDNStrue;
        else
            return mDNSfalse;
    }
    
    // Sent record if it is explicitly marked to include all other P2P type interfaces.
    if (rr->ARType == AuthRecordAnyIncludeP2P)
        return mDNStrue;

    // Don't send the record over this interface.
    return mDNSfalse;
}

// Filter questions send over P2P (D2D) type interfaces.
mDNSexport mDNSBool mDNSPlatformValidQuestionForInterface(DNSQuestion *q, const NetworkInterfaceInfo *intf)
{
    // For an explicit match to a valid interface ID, return true. 
    if (q->InterfaceID == intf->InterfaceID)
        return mDNStrue;

    // Only filtering questions for D2D type interfaces
    if (!mDNSPlatformInterfaceIsD2D(intf->InterfaceID))
        return mDNStrue;

    // If it's an AWDL interface the question must be explicitly marked to include AWDL.
    if (intf->InterfaceID == AWDLInterfaceID)
    {
        if (q->flags & kDNSServiceFlagsIncludeAWDL)
            return mDNStrue;
        else
            return mDNSfalse;
    }
    
    // Sent question if it is explicitly marked to include all other P2P type interfaces.
    if (q->flags & kDNSServiceFlagsIncludeP2P)
        return mDNStrue;

    // Don't send the question over this interface.
    return mDNSfalse;
}

// Returns true unless record was received over the AWDL interface and
// the question was not specific to the AWDL interface or did not specify kDNSServiceInterfaceIndexAny
// with the kDNSServiceFlagsIncludeAWDL flag set.
mDNSexport mDNSBool   mDNSPlatformValidRecordForQuestion(const ResourceRecord *const rr, const DNSQuestion *const q)
{
    if (!rr->InterfaceID || (rr->InterfaceID == q->InterfaceID))
        return mDNStrue;

    if ((rr->InterfaceID == AWDLInterfaceID) && !(q->flags & kDNSServiceFlagsIncludeAWDL))
    {
        LogInfo("mDNSPlatformValidRecordForQuestion: Record recieved over AWDL not returned for %s %##s query",
                DNSTypeName(q->qtype), q->qname.c);
        return mDNSfalse;
    }

    return mDNStrue;
}

// formating time to RFC 4034 format
mDNSexport void mDNSPlatformFormatTime(unsigned long te, mDNSu8 *buf, int bufsize)
{
    struct tm tmTime;
    time_t t = (time_t)te;
    // Time since epoch : strftime takes "tm". Convert seconds to "tm" using
    // gmtime_r first and then use strftime
    gmtime_r(&t, &tmTime);
    strftime((char *)buf, bufsize, "%Y%m%d%H%M%S", &tmTime);
}

mDNSexport mStatus mDNSPlatformRetrieveTCPInfo(mDNS *const m, mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti)
{
    struct tcp_info ti;
    struct info_tuple itpl;
    int mib[4];
    unsigned int miblen;
    size_t len;
    size_t sz;

    itpl.itpl_proto = IPPROTO_TCP;

    if (laddr->type == mDNSAddrType_IPv4)
    {
        mDNSPlatformMemCopy(&itpl.itpl_local_sin.sin_addr, &laddr->ip.v4, sizeof(struct in_addr));
        mDNSPlatformMemCopy(&itpl.itpl_remote_sin.sin_addr, &raddr->ip.v4, sizeof(struct in_addr));
        itpl.itpl_local_sin.sin_port = lport->NotAnInteger;
        itpl.itpl_remote_sin.sin_port = rport->NotAnInteger;
        itpl.itpl_remote_sin.sin_family = AF_INET;
    }
    else
    {
        mDNSPlatformMemCopy(&itpl.itpl_local_sin6.sin6_addr, &laddr->ip.v6, sizeof(struct in6_addr));
        mDNSPlatformMemCopy(&itpl.itpl_remote_sin6.sin6_addr, &raddr->ip.v6, sizeof(struct in6_addr));
        itpl.itpl_local_sin6.sin6_port = lport->NotAnInteger;
        itpl.itpl_remote_sin6.sin6_port = rport->NotAnInteger;
        itpl.itpl_remote_sin6.sin6_family = AF_INET6;
    }


    sz = sizeof(mib)/sizeof(mib[0]);
    if (sysctlnametomib("net.inet.tcp.info", mib, &sz) == -1)
    {
        LogMsg("mDNSPlatformRetrieveTCPInfo: sysctlnametomib failed %d, %s", errno, strerror(errno));
        return mStatus_UnknownErr;
    }

    miblen = (unsigned int)sz;

    len = sizeof(struct tcp_info);
    if (sysctl(mib, miblen, &ti, &len, &itpl, sizeof(struct info_tuple)) == -1)
    {
        LogMsg("mDNSPlatformRetrieveTCPInfo: sysctl failed %d, %s", errno, strerror(errno));
        return mStatus_UnknownErr;
    }
    mti->seq = ti.tcpi_snd_nxt - 1;
    mti->ack = ti.tcpi_rcv_nxt;
    mti->window = ti.tcpi_rcv_space >> ti.tcpi_rcv_wscale;
    mti->IntfId = mDNSPlatformInterfaceIDfromInterfaceIndex(m,  ti.tcpi_last_outif);
    if (mti->IntfId == mDNSInterface_LocalOnly || mti->IntfId == mDNSInterface_P2P || mti->IntfId == mDNSInterface_Any)
    {
        LogMsg("mDNSPlatformRetrieveTCPInfo: Bad InterfaceId %p", mti->IntfId);
        return mStatus_BadParamErr;
    }

    return mStatus_NoError;
}

#if APPLE_OSX_mDNSResponder
mDNSexport void mDNSPlatformToggleInterfaceAdvt(mDNS *const m, mDNSBool stopAdvt)
{
    NetworkInterfaceInfoOSX *intf;

    LogInfo("%s called to %s advertisements", __func__, stopAdvt? "stop" : "start");
    for (intf = m->p->InterfaceList; intf; intf = intf->next)
    {
        // For now, the ioctl only supports suppression of IPv6 advertisements
        if (intf->ifinfo.InterfaceActive && intf->ifinfo.McastTxRx)
        {
            if (mDNSInterfaceAdvtIoctl(intf->ifinfo.ifname, (stopAdvt? 0 : 1)) < 0)
            {
                LogMsg("%s: mDNSInterfaceAdvtIoctl failed");
            }
        }
    }
}
#endif
