Imported Upstream version 878.70.2
[platform/upstream/mdnsresponder.git] / mDNSCore / uDNS.c
index 3677b9f..64dae89 100755 (executable)
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 4 -*-
  *
- * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2017 Apple Inc. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #endif
 #include "uDNS.h"
 
+#if AWD_METRICS
+#include "Metrics.h"
+#endif
+
 #if (defined(_MSC_VER))
 // Disable "assignment within conditional expression".
 // Other compilers understand the convention that if you place the assignment expression within an extra pair
@@ -45,12 +49,12 @@ mDNSexport SearchListElem *SearchList = mDNSNULL;
 mDNSBool StrictUnicastOrdering = mDNSfalse;
 
 // We keep track of the number of unicast DNS servers and log a message when we exceed 64.
-// Currently the unicast queries maintain a 64 bit map to track the valid DNS servers for that
+// Currently the unicast queries maintain a 128 bit map to track the valid DNS servers for that
 // question. Bit position is the index into the DNS server list. This is done so to try all
 // the servers exactly once before giving up. If we could allocate memory in the core, then
-// arbitrary limitation of 64 DNSServers can be removed.
+// arbitrary limitation of 128 DNSServers can be removed.
 mDNSu8 NumUnicastDNSServers = 0;
-#define MAX_UNICAST_DNS_SERVERS 64
+#define MAX_UNICAST_DNS_SERVERS 128
 #if APPLE_OSX_mDNSResponder
 mDNSu8 NumUnreachableDNSServers = 0;
 #endif
@@ -112,8 +116,8 @@ mDNSlocal void SetRecordRetry(mDNS *const m, AuthRecord *rr, mDNSu32 random)
 #endif
 
 mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSs32 serviceID, const mDNSAddr *addr,
-                                        const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSu16 resGroupID, mDNSBool reqA,
-                                        mDNSBool reqAAAA, mDNSBool reqDO)
+                                        const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSu16 resGroupID,
+                                        mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO)
 {
     DNSServer **p = &m->DNSServers;
     DNSServer *tmp = mDNSNULL;
@@ -127,9 +131,9 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
     if (!d)
         d = (const domainname *)"";
 
-    LogInfo("mDNS_AddDNSServer(%d): Adding %#a for %##s, InterfaceID %p, serviceID %u, scoped %d, resGroupID %d req_A is %s req_AAAA is %s cell %s req_DO is %s",
+    LogInfo("mDNS_AddDNSServer(%d): Adding %#a for %##s, InterfaceID %p, serviceID %u, scoped %d, resGroupID %d req_A is %s req_AAAA is %s cell %s isExpensive %s req_DO is %s",
         NumUnicastDNSServers, addr, d->c, interface, serviceID, scoped, resGroupID, reqA ? "True" : "False", reqAAAA ? "True" : "False",
-        cellIntf ? "True" : "False", reqDO ? "True" : "False");
+        cellIntf ? "True" : "False", isExpensive ? "True" : "False", reqDO ? "True" : "False");
 
     mDNS_CheckLock(m);
 
@@ -186,17 +190,18 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
         }
         else
         {
-            (*p)->scoped    = scoped;
-            (*p)->interface = interface;
-            (*p)->serviceID = serviceID;
-            (*p)->addr      = *addr;
-            (*p)->port      = port;
-            (*p)->flags     = DNSServer_FlagNew;
-            (*p)->timeout   = timeout;
-            (*p)->cellIntf  = cellIntf;
-            (*p)->req_A     = reqA;
-            (*p)->req_AAAA  = reqAAAA;
-            (*p)->req_DO    = reqDO;
+            (*p)->scoped      = scoped;
+            (*p)->interface   = interface;
+            (*p)->serviceID   = serviceID;
+            (*p)->addr        = *addr;
+            (*p)->port        = port;
+            (*p)->flags       = DNSServer_FlagNew;
+            (*p)->timeout     = timeout;
+            (*p)->cellIntf    = cellIntf;
+            (*p)->isExpensive = isExpensive;
+            (*p)->req_A       = reqA;
+            (*p)->req_AAAA    = reqAAAA;
+            (*p)->req_DO      = reqDO;
             // We start off assuming that the DNS server is not DNSSEC aware and
             // when we receive the first response to a DNSSEC question, we set
             // it to true.
@@ -485,7 +490,7 @@ mDNSlocal mStatus uDNS_RequestAddress(mDNS *m)
 
     if (!m->NATTraversals)
     {
-        m->retryGetAddr = NonZeroTime(m->timenow + 0x78000000);
+        m->retryGetAddr = NonZeroTime(m->timenow + FutureTime);
         LogInfo("uDNS_RequestAddress: Setting retryGetAddr to future");
     }
     else if (m->timenow - m->retryGetAddr >= 0)
@@ -545,7 +550,7 @@ mDNSlocal mStatus uDNS_RequestAddress(mDNS *m)
     return err;
 }
 
-mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info, mDNSBool usePCP)
+mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info, mDNSBool usePCP, mDNSBool unmapping)
 {
     mStatus err = mStatus_NoError;
 
@@ -644,19 +649,25 @@ mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info, mDNSBool useP
             info->sentNATPMP = mDNSfalse;
 
 #ifdef _LEGACY_NAT_TRAVERSAL_
-            if (mDNSIPPortIsZero(m->UPnPRouterPort) || mDNSIPPortIsZero(m->UPnPSOAPPort))
-            {
-                LNT_SendDiscoveryMsg(m);
-                debugf("uDNS_SendNATMsg: LNT_SendDiscoveryMsg");
-            }
-            else
+            // If an unmapping is being performed, then don't send an LNT discovery message or an LNT port map request.
+            if (!unmapping)
             {
-                mStatus lnterr = LNT_MapPort(m, info);
-                if (lnterr)
-                    LogMsg("uDNS_SendNATMsg: LNT_MapPort returned error %d", lnterr);
+                if (mDNSIPPortIsZero(m->UPnPRouterPort) || mDNSIPPortIsZero(m->UPnPSOAPPort))
+                {
+                    LNT_SendDiscoveryMsg(m);
+                    debugf("uDNS_SendNATMsg: LNT_SendDiscoveryMsg");
+                }
+                else
+                {
+                    mStatus lnterr = LNT_MapPort(m, info);
+                    if (lnterr)
+                        LogMsg("uDNS_SendNATMsg: LNT_MapPort returned error %d", lnterr);
 
-                err = err ? err : lnterr; // PCP error takes precedence
+                    err = err ? err : lnterr; // PCP error takes precedence
+                }
             }
+#else
+            (void)unmapping; // Unused
 #endif // _LEGACY_NAT_TRAVERSAL_
         }
     }
@@ -920,6 +931,16 @@ mDNSexport mStatus mDNS_StopNATOperation_internal(mDNS *m, NATTraversalInfo *tra
         }
     }
 
+    // Even if we DIDN'T make a successful UPnP mapping yet, we might still have a partially-open TCP connection we need to clean up
+    // Before zeroing traversal->RequestedPort below, perform the LNT unmapping, which requires the mapping's external port,
+    // held by the traversal->RequestedPort variable.
+    #ifdef _LEGACY_NAT_TRAVERSAL_
+    {
+        mStatus err = LNT_UnmapPort(m, traversal);
+        if (err) LogMsg("Legacy NAT Traversal - unmap request failed with error %d", err);
+    }
+    #endif // _LEGACY_NAT_TRAVERSAL_
+
     if (traversal->ExpiryTime && unmap)
     {
         traversal->NATLease = 0;
@@ -941,17 +962,9 @@ mDNSexport mStatus mDNS_StopNATOperation_internal(mDNS *m, NATTraversalInfo *tra
         traversal->RequestedPort = zeroIPPort;
         traversal->NewAddress = zerov4Addr;
 
-        uDNS_SendNATMsg(m, traversal, traversal->lastSuccessfulProtocol != NATTProtocolNATPMP);
+        uDNS_SendNATMsg(m, traversal, traversal->lastSuccessfulProtocol != NATTProtocolNATPMP, mDNStrue);
     }
 
-    // Even if we DIDN'T make a successful UPnP mapping yet, we might still have a partially-open TCP connection we need to clean up
-    #ifdef _LEGACY_NAT_TRAVERSAL_
-    {
-        mStatus err = LNT_UnmapPort(m, traversal);
-        if (err) LogMsg("Legacy NAT Traversal - unmap request failed with error %d", err);
-    }
-    #endif // _LEGACY_NAT_TRAVERSAL_
-
     return(mStatus_NoError);
 }
 
@@ -1328,6 +1341,12 @@ mDNSlocal void tcpCallback(TCPSocket *sock, void *context, mDNSBool ConnectionEs
 
         err = mDNSSendDNSMessage(m, &tcpInfo->request, end, mDNSInterface_Any, mDNSNULL, &tcpInfo->Addr, tcpInfo->Port, sock, AuthInfo, mDNSfalse);
         if (err) { debugf("ERROR: tcpCallback: mDNSSendDNSMessage - %d", err); err = mStatus_UnknownErr; goto exit; }
+#if AWD_METRICS
+        if (mDNSSameIPPort(tcpInfo->Port, UnicastDNSPort))
+        {
+            MetricsUpdateDNSQuerySize((mDNSu32)(end - (mDNSu8 *)&tcpInfo->request));
+        }
+#endif
 
         // Record time we sent this question
         if (q)
@@ -1554,7 +1573,7 @@ mDNSlocal tcpInfo_t *MakeTCPConn(mDNS *const m, const DNSMessage *const msg, con
     mDNSPlatformMemZero(info, sizeof(tcpInfo_t));
 
     info->m          = m;
-    info->sock       = mDNSPlatformTCPSocket(m, flags, &srcport, useBackgroundTrafficClass);
+    info->sock       = mDNSPlatformTCPSocket(flags, &srcport, useBackgroundTrafficClass);
     info->requestLen = 0;
     info->question   = question;
     info->rr         = rr;
@@ -1720,7 +1739,7 @@ mDNSexport const domainname *GetServiceTarget(mDNS *m, AuthRecord *const rr)
         DomainAuthInfo *AuthInfo = GetAuthInfoForName_internal(m, rr->resrec.name);
         if (AuthInfo && AuthInfo->AutoTunnel)
         {
-            StartServerTunnel(m, AuthInfo);
+            StartServerTunnel(AuthInfo);
             if (AuthInfo->AutoTunnelHostRecord.namestorage.c[0] == 0) return(mDNSNULL);
             debugf("GetServiceTarget: Returning %##s", AuthInfo->AutoTunnelHostRecord.namestorage.c);
             return(&AuthInfo->AutoTunnelHostRecord.namestorage);
@@ -2759,7 +2778,6 @@ mDNSexport void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, co
         m->NextSRVUpdate = NonZeroTime(m->timenow);
 
 #if APPLE_OSX_mDNSResponder
-        if (RouterChanged) uuid_generate(m->asl_uuid);
         UpdateAutoTunnelDomainStatuses(m);
 #endif
     }
@@ -3034,7 +3052,6 @@ exit:
 mDNSlocal mDNSBool IsRecordMergeable(mDNS *const m, AuthRecord *rr, mDNSs32 time)
 {
     DomainAuthInfo *info;
-    (void) m; //unused
     // A record is eligible for merge, if the following properties are met.
     //
     // 1. uDNS Resource Record
@@ -3651,7 +3668,7 @@ mDNSlocal void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID Interface
         {
             // Send a NAT-PMP request for this operation as needed
             // and update the state variables
-            uDNS_SendNATMsg(m, n, mDNSfalse);
+            uDNS_SendNATMsg(m, n, mDNSfalse, mDNSfalse);
         }
 
         m->NextScheduledNATOp = m->timenow;
@@ -3697,9 +3714,7 @@ mDNSlocal void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID Interface
     if (AddrReply->opcode == NATOp_AddrResponse)
     {
 #if APPLE_OSX_mDNSResponder
-        static char msgbuf[16];
-        mDNS_snprintf(msgbuf, sizeof(msgbuf), "%d", AddrReply->err);
-        mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.natpmp.AddressRequest", AddrReply->err ? "failure" : "success", msgbuf, "");
+        LogInfo("uDNS_ReceiveNATPMPPacket: AddressRequest %s error %d", AddrReply->err ? "failure" : "success", AddrReply->err);
 #endif
         if (!AddrReply->err && len < sizeof(NATAddrReply)) { LogMsg("NAT-PMP AddrResponse message too short (%d bytes)", len); return; }
         natTraversalHandleAddressReply(m, AddrReply->err, AddrReply->ExtAddr);
@@ -3708,9 +3723,8 @@ mDNSlocal void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID Interface
     {
         mDNSu8 Protocol = AddrReply->opcode & 0x7F;
 #if APPLE_OSX_mDNSResponder
-        static char msgbuf[16];
-        mDNS_snprintf(msgbuf, sizeof(msgbuf), "%s - %d", AddrReply->opcode == NATOp_MapUDPResponse ? "UDP" : "TCP", PortMapReply->err);
-        mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.natpmp.PortMapRequest", PortMapReply->err ? "failure" : "success", msgbuf, "");
+        LogInfo("uDNS_ReceiveNATPMPPacket: PortMapRequest %s %s - error %d",
+            PortMapReply->err ? "failure" : "success", (AddrReply->opcode == NATOp_MapUDPResponse) ? "UDP" : "TCP", PortMapReply->err);
 #endif
         if (!PortMapReply->err)
         {
@@ -3921,7 +3935,9 @@ mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNS
 
     if (QR_OP == UpdateR)
     {
-        mDNSu32 lease = GetPktLease(m, msg, end);
+        mDNSu32 pktlease = 0;
+        mDNSBool gotlease = GetPktLease(m, msg, end, &pktlease);
+        mDNSu32 lease = gotlease ? pktlease : 60 * 60; // If lease option missing, assume one hour
         mDNSs32 expire = m->timenow + (mDNSs32)lease * mDNSPlatformOneSecond;
         mDNSu32 random = mDNSRandom((mDNSs32)lease * mDNSPlatformOneSecond/10);
 
@@ -4088,6 +4104,7 @@ mDNSexport void LLQGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneI
     mDNS_Unlock(m);
 }
 
+#ifdef DNS_PUSH_ENABLED
 mDNSexport void DNSPushNotificationGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo)
 {
     DNSQuestion *q = (DNSQuestion *)zoneInfo->ZoneDataContext;
@@ -4120,7 +4137,7 @@ mDNSexport void DNSPushNotificationGotZoneData(mDNS *const m, mStatus err, const
     }
     mDNS_Unlock(m);
 }
-
+#endif // DNS_PUSH_ENABLED
 
 // Called in normal callback context (i.e. mDNS_busy and mDNS_reentrancy are both 1)
 mDNSlocal void PrivateQueryGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo)
@@ -4625,9 +4642,11 @@ mDNSlocal void handle_unanswered_query(mDNS *const m)
 
 mDNSlocal void uDNS_HandleLLQState(mDNS *const m, DNSQuestion *q)
 {
+#ifdef DNS_PUSH_ENABLED
     // First attempt to use DNS Push Notification.
     if (q->dnsPushState == DNSPUSH_INIT)
         DiscoverDNSPushNotificationServer(m, q);
+#endif // DNS_PUSH_ENABLED
     switch (q->state)
     {
         case LLQ_InitialRequest:   startLLQHandshake(m, q); break;
@@ -4733,9 +4752,20 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
                     debugf("uDNS_CheckCurrentQuestion sending %p %##s (%s) %#a:%d UnansweredQueries %d",
                            q, q->qname.c, DNSTypeName(q->qtype),
                            q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL, mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zeroIPPort), q->unansweredQueries);
+#if APPLE_OSX_mDNSResponder
+                    // When a DNS proxy network extension initiates the close of a UDP flow (this usually happens when a DNS
+                    // proxy gets disabled or crashes), mDNSResponder's corresponding UDP socket will be marked with the
+                    // SS_CANTRCVMORE state flag. Reading from such a socket is no longer possible, so close the current
+                    // socket pair so that we can create a new pair.
+                    if (q->LocalSocket && mDNSPlatformUDPSocketEncounteredEOF(q->LocalSocket))
+                    {
+                        mDNSPlatformUDPClose(q->LocalSocket);
+                        q->LocalSocket = mDNSNULL;
+                    }
+#endif
                     if (!q->LocalSocket)
                     {
-                        q->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
+                        q->LocalSocket = mDNSPlatformUDPSocket(zeroIPPort);
                         if (q->LocalSocket)
                         {
                             mDNSPlatformSetSocktOpt(q->LocalSocket, mDNSTransport_UDP, mDNSAddrType_IPv4, q);
@@ -4746,9 +4776,10 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
                     else
                     {
                         err = mDNSSendDNSMessage(m, &m->omsg, end, q->qDNSServer->interface, q->LocalSocket, &q->qDNSServer->addr, q->qDNSServer->port, mDNSNULL, mDNSNULL, q->UseBackgroundTrafficClass);
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
                         if (!err)
                         {
+                            MetricsUpdateDNSQuerySize((mDNSu32)(end - (mDNSu8 *)&m->omsg));
                             if (q->metrics.answered)
                             {
                                 q->metrics.querySendCount = 0;
@@ -4777,8 +4808,18 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
                 }
 
                 newServer = GetServerForQuestion(m, q);
-                DNSServerChangeForQuestion(m, q, newServer);
-
+                if (!newServer)
+                {
+                    q->triedAllServersOnce = 1;
+                    SetValidDNSServers(m, q);
+                    newServer = GetServerForQuestion(m, q);
+                }
+                if (newServer)
+                {
+                    LogInfo("uDNS_checkCurrentQuestion: Retrying question %p %##s (%s) DNS Server %#a:%u ThisQInterval %d",
+                        q, q->qname.c, DNSTypeName(q->qtype), newServer ? &newServer->addr : mDNSNULL, mDNSVal16(newServer ? newServer->port : zeroIPPort), q->ThisQInterval);
+                    DNSServerChangeForQuestion(m, q, newServer);
+                }
                 if (q->triedAllServersOnce)
                 {
                     q->LastQTime = m->timenow;
@@ -4789,7 +4830,6 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
                     q->LastQTime     = m->timenow - q->ThisQInterval;
                 }
                 q->unansweredQueries = 0;
-                q->noServerResponse  = 1;
             }
             else
             {
@@ -4839,20 +4879,20 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
             // passed to uDNS_CheckCurrentQuestion -- we only want one set of query packets hitting the wire --
             // but we want *all* of the questions to get answer callbacks.)
             CacheRecord *rr;
-            const mDNSu32 slot = HashSlot(&q->qname);
-            CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+            const mDNSu32 slot = HashSlotFromNameHash(q->qnamehash);
+            CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
 
             if (!q->qDNSServer)
             {
-                if (!mDNSOpaque64IsZero(&q->validDNSServers))
-                    LogMsg("uDNS_CheckCurrentQuestion: ERROR!!: valid DNSServer bits not zero 0x%x, 0x%x for question %##s (%s)",
-                           q->validDNSServers.l[1], q->validDNSServers.l[0], q->qname.c, DNSTypeName(q->qtype));
+                if (!mDNSOpaque128IsZero(&q->validDNSServers))
+                    LogMsg("uDNS_CheckCurrentQuestion: ERROR!!: valid DNSServer bits not zero 0x%x, 0x%x 0x%x 0x%x for question %##s (%s)",
+                           q->validDNSServers.l[3], q->validDNSServers.l[2], q->validDNSServers.l[1], q->validDNSServers.l[0], q->qname.c, DNSTypeName(q->qtype));
                 // If we reached the end of list while picking DNS servers, then we don't want to deactivate the
                 // question. Try after 60 seconds. We find this by looking for valid DNSServers for this question,
                 // if we find any, then we must have tried them before we came here. This avoids maintaining
                 // another state variable to see if we had valid DNS servers for this question.
                 SetValidDNSServers(m, q);
-                if (mDNSOpaque64IsZero(&q->validDNSServers))
+                if (mDNSOpaque128IsZero(&q->validDNSServers))
                 {
                     LogInfo("uDNS_CheckCurrentQuestion: no DNS server for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
                     q->ThisQInterval = 0;
@@ -4916,7 +4956,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
 {
     mDNSBool rfc1918 = mDNSv4AddrIsRFC1918(&m->AdvertisedV4.ip.v4);
     mDNSBool HaveRoutable = !rfc1918 && !mDNSIPv4AddressIsZero(m->AdvertisedV4.ip.v4);
-    m->NextScheduledNATOp = m->timenow + 0x3FFFFFFF;
+    m->NextScheduledNATOp = m->timenow + FutureTime;
 
     if (HaveRoutable) m->ExtAddress = m->AdvertisedV4.ip.v4;
 
@@ -4926,7 +4966,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
         {
             // we need to log a message if we can't get our socket, but only the first time (after success)
             static mDNSBool needLog = mDNStrue;
-            m->NATMcastRecvskt = mDNSPlatformUDPSocket(m, NATPMPAnnouncementPort);
+            m->NATMcastRecvskt = mDNSPlatformUDPSocket(NATPMPAnnouncementPort);
             if (!m->NATMcastRecvskt)
             {
                 if (needLog)
@@ -4971,7 +5011,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
                     cur->retryInterval = NATMAP_INIT_RETRY;
                 }
 
-                uDNS_SendNATMsg(m, cur, mDNStrue); // Will also do UPnP discovery for us, if necessary
+                uDNS_SendNATMsg(m, cur, mDNStrue, mDNSfalse); // Will also do UPnP discovery for us, if necessary
 
                 if (cur->ExpiryTime)                        // If have active mapping then set next renewal time halfway to expiry
                     NATSetNextRenewalTime(m, cur);
@@ -5047,7 +5087,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
 mDNSlocal mDNSs32 CheckRecordUpdates(mDNS *m)
 {
     AuthRecord *rr;
-    mDNSs32 nextevent = m->timenow + 0x3FFFFFFF;
+    mDNSs32 nextevent = m->timenow + FutureTime;
 
     CheckGroupRecordUpdates(m);
 
@@ -5105,7 +5145,7 @@ mDNSexport void uDNS_Tasks(mDNS *const m)
     mDNSs32 nexte;
     DNSServer *d;
 
-    m->NextuDNSEvent = m->timenow + 0x3FFFFFFF;
+    m->NextuDNSEvent = m->timenow + FutureTime;
 
     nexte = CheckRecordUpdates(m);
     if (m->NextuDNSEvent - nexte > 0)
@@ -5400,7 +5440,7 @@ mDNSexport void uDNS_SetupWABQueries(mDNS *const m)
     // Make sure we have the search domains from the platform layer so that if we start the WAB
     // queries below, we have the latest information.
     mDNS_Lock(m);
-    if (!mDNSPlatformSetDNSConfig(m, mDNSfalse, mDNStrue, mDNSNULL, mDNSNULL, mDNSNULL, mDNSfalse))
+    if (!mDNSPlatformSetDNSConfig(mDNSfalse, mDNStrue, mDNSNULL, mDNSNULL, mDNSNULL, mDNSfalse))
     {
         // If the configuration did not change, clear the flag so that we don't free the searchlist.
         // We still have to start the domain enumeration queries as we may not have started them
@@ -5648,11 +5688,10 @@ mDNSexport void uDNS_StopWABQueries(mDNS *const m, int queryType)
     uDNS_SetupWABQueries(m);
 }
 
-mDNSexport domainname  *uDNS_GetNextSearchDomain(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal)
+mDNSexport domainname  *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal)
 {
     SearchListElem *p = SearchList;
     int count = *searchIndex;
-    (void) m; // unused
 
     if (count < 0) { LogMsg("uDNS_GetNextSearchDomain: count %d less than zero", count); return mDNSNULL; }
 
@@ -5775,10 +5814,15 @@ struct CompileTimeAssertionChecks_uDNS
 #pragma mark - DNS Push Notification functions
 #endif
 
+#ifdef DNS_PUSH_ENABLED
 mDNSlocal tcpInfo_t * GetTCPConnectionToPushServer(mDNS *m, DNSQuestion *q)
 {
+    DNSPushNotificationZone   *zone;
+    DNSPushNotificationServer *server;
+    DNSPushNotificationZone   *newZone;
+    DNSPushNotificationServer *newServer;
+
     // If we already have a question for this zone and if the server is the same, reuse it
-    DNSPushNotificationZone *zone = mDNSNULL;
     for (zone = m->DNSPushZones; zone != mDNSNULL; zone = zone->next)
     {
         if (SameDomainName(&q->nta->ChildName, &zone->zoneName))
@@ -5797,12 +5841,11 @@ mDNSlocal tcpInfo_t * GetTCPConnectionToPushServer(mDNS *m, DNSQuestion *q)
     }
 
     // If we have a connection to this server but it is for a differnt zone, create a new zone entry and reuse the connection
-    DNSPushNotificationServer *server = mDNSNULL;
     for (server = m->DNSPushServers; server != mDNSNULL; server = server->next)
     {
         if (mDNSSameAddress(&q->dnsPushServerAddr, &server->serverAddr))
         {
-            DNSPushNotificationZone *newZone = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationZone));
+            newZone = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationZone));
             newZone->numberOfQuestions = 1;
             newZone->zoneName = q->nta->ChildName;
             newZone->servers = server;
@@ -5817,8 +5860,8 @@ mDNSlocal tcpInfo_t * GetTCPConnectionToPushServer(mDNS *m, DNSQuestion *q)
     }
 
     // If we do not have any existing connections, create a new connection
-    DNSPushNotificationServer *newServer = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationServer));
-    DNSPushNotificationZone   *newZone   = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationZone));
+    newServer = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationServer));
+    newZone   = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationZone));
 
     newServer->numberOfQuestions = 1;
     newServer->serverAddr = q->dnsPushServerAddr;
@@ -5930,6 +5973,9 @@ mDNSlocal  void reconcileDNSPushConnection(mDNS *m, DNSQuestion *q)
 {
     DNSPushNotificationZone   *zone;
     DNSPushNotificationServer *server;
+    DNSPushNotificationServer *nextServer;
+    DNSPushNotificationZone   *nextZone;
+
     // Update the counts
     for (zone = m->DNSPushZones; zone != mDNSNULL; zone = zone->next)
     {
@@ -5946,7 +5992,7 @@ mDNSlocal  void reconcileDNSPushConnection(mDNS *m, DNSQuestion *q)
 
     // Now prune the lists
     server = m->DNSPushServers;
-    DNSPushNotificationServer *nextServer = mDNSNULL;
+    nextServer = mDNSNULL;
     while(server != mDNSNULL)
     {
         nextServer = server->next;
@@ -5962,7 +6008,7 @@ mDNSlocal  void reconcileDNSPushConnection(mDNS *m, DNSQuestion *q)
     }
 
     zone = m->DNSPushZones;
-    DNSPushNotificationZone *nextZone = mDNSNULL;
+    nextZone = mDNSNULL;
     while(zone != mDNSNULL)
     {
         nextZone = zone->next;
@@ -5994,6 +6040,7 @@ mDNSexport void UnSubscribeToDNSPushNotificationServer(mDNS *m, DNSQuestion *q)
     reconcileDNSPushConnection(m, q);
 }
 
+#endif // DNS_PUSH_ENABLED
 #if COMPILER_LIKES_PRAGMA_MARK
 #pragma mark -
 #endif
@@ -6119,9 +6166,8 @@ mDNSexport mStatus mDNS_SetSecretForDomain(mDNS *m, DomainAuthInfo *info, const
     return mStatus_UnsupportedErr;
 }
 
-mDNSexport domainname  *uDNS_GetNextSearchDomain(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal)
+mDNSexport domainname  *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal)
 {
-    (void) m;
     (void) InterfaceID;
     (void) searchIndex;
     (void) ignoreDotLocal;
@@ -6154,8 +6200,8 @@ mDNSexport mStatus mDNS_StopNATOperation(mDNS *const m, NATTraversalInfo *traver
 }
 
 mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSs32 serviceID, const mDNSAddr *addr,
-                                        const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSu16 resGroupID, mDNSBool reqA,
-                                        mDNSBool reqAAAA, mDNSBool reqDO)
+                                        const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSu16 resGroupID,
+                                        mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO)
 {
     (void) m;
     (void) d;
@@ -6166,6 +6212,7 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
     (void) scoped;
     (void) timeout;
     (void) cellIntf;
+    (void) isExpensive;
     (void) resGroupID;
     (void) reqA;
     (void) reqAAAA;