]> git.saurik.com Git - apple/mdnsresponder.git/commitdiff
mDNSResponder-576.30.4.tar.gz os-x-10104 os-x-10105 v576.30.4
authorApple <opensource@apple.com>
Mon, 6 Jul 2015 06:03:38 +0000 (06:03 +0000)
committerApple <opensource@apple.com>
Mon, 6 Jul 2015 06:03:38 +0000 (06:03 +0000)
24 files changed:
Clients/dns-sd.c
Clients/dnsctl.c
Makefile
mDNSCore/DNSCommon.c
mDNSCore/mDNS.c
mDNSCore/mDNSEmbeddedAPI.h
mDNSCore/uDNS.c
mDNSMacOSX/CUPolicy.c
mDNSMacOSX/LaunchDaemonInfo.helper.plist
mDNSMacOSX/LaunchDaemonInfo.plist
mDNSMacOSX/Private/dns_services.c
mDNSMacOSX/Private/dns_services.h [new file with mode: 0644]
mDNSMacOSX/Private/dns_services_mdns.h [deleted file]
mDNSMacOSX/VPNService.c
mDNSMacOSX/daemon.c
mDNSMacOSX/mDNSMacOSX.c
mDNSMacOSX/mDNSResponder-entitlements.plist
mDNSMacOSX/mDNSResponder.sb
mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj
mDNSPosix/mDNSPosix.c
mDNSShared/dns_sd.h
mDNSShared/dnssd_clientshim.c
mDNSShared/dnssd_clientstub.c
mDNSShared/uds_daemon.c

index 61c7dcd63beb26161bad3c4dc41db7652519119d..9acf41e581c521d6eda7b8b40e8915798265a79b 100644 (file)
@@ -1617,6 +1617,7 @@ int main(int argc, char **argv)
         err = RegisterService(&client, argv[opi+0], typ, dom, NULL, argv[opi+3], argc-(opi+4), argv+(opi+4), flags);
         break;
 
+
     case 'P':   if (argc < opi+6) goto Fail;
         err = DNSServiceCreateConnection(&client_pa);
         if (err) { fprintf(stderr, "DNSServiceCreateConnection returned %d\n", err); return(err); }
@@ -1631,7 +1632,7 @@ int main(int argc, char **argv)
     case 'C':   {
         uint16_t rrtype, rrclass;
         flags |= kDNSServiceFlagsReturnIntermediates;
-        if (operation == 'q') 
+        if (operation == 'q')
             flags |= kDNSServiceFlagsSuppressUnusable;
         if (argc < opi+1) 
             goto Fail;
index b557ac323970889e8e733a1559adacbcaa6761ee..bb2a0716ed1e1a5eadaf90664ab111c5116234fa 100644 (file)
@@ -18,7 +18,7 @@
 #include <net/if.h> // if_nametoindex()
 
 #include <dispatch/dispatch.h>
-#include "dns_services_mdns.h"
+#include "dns_services.h"
 
 //*************************************************************************************************************
 // Globals:
index d7c1919d9494cfece06ef0595c647f56837a40e1..647dcf95cdf8fc3e215634de8f056174cd298463 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@
 
 include $(MAKEFILEPATH)/pb_makefiles/platform.make
 
-MVERS = "mDNSResponder-567"
+MVERS = "mDNSResponder-576.30.4"
 
 DDNSWRITECONFIG = "$(DSTROOT)/Library/Application Support/Bonjour/ddnswriteconfig"
 VER = 
index 3b2f2ceb3bf5221fb6c098eba122417a76d411c6..249e3b235009f6138230b75c6520fc41bf19ac22 100644 (file)
@@ -1467,6 +1467,8 @@ mDNSexport void mDNS_SetupQuestion(DNSQuestion *const q, const mDNSInterfaceID I
     q->ForceMCast          = mDNSfalse;
     q->ReturnIntermed      = mDNSfalse;
     q->SuppressUnusable    = mDNSfalse;
+    q->DenyOnCellInterface = mDNSfalse;
+    q->DenyOnExpInterface  = mDNSfalse;
     q->SearchListIndex     = 0;
     q->AppendSearchDomains = 0;
     q->RetryWithSearchDomains = mDNSfalse;
index e15b7cf8a196ec576b077ba0772476dc26cbe818..e0af1f1a0562c0e8f6c333f561e32b534a21bb4e 100755 (executable)
@@ -466,8 +466,10 @@ mDNSexport void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, Re
 {
     const mDNSBool selfref = SameDomainName(&q->qname, &rr->rdata->u.name);
     if (q->CNAMEReferrals >= 10 || selfref)
+    {
         LogMsg("AnswerQuestionByFollowingCNAME: %p %##s (%s) NOT following CNAME referral %d%s for %s",
                q, q->qname.c, DNSTypeName(q->qtype), q->CNAMEReferrals, selfref ? " (Self-Referential)" : "", RRDisplayString(m, rr));
+    }
     else
     {
         const mDNSu32 c = q->CNAMEReferrals + 1;        // Stash a copy of the new q->CNAMEReferrals value
@@ -1254,19 +1256,6 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
         }
     }
 
-    // If this resource record is referencing a specific interface, make sure it exists.
-    // Skip checks for LocalOnly and P2P as they are not valid InterfaceIDs. Also, for scoped
-    // entries in /etc/hosts skip that check as that interface may not be valid at this time.
-    if (rr->resrec.InterfaceID && rr->ARType != AuthRecordLocalOnly && rr->ARType != AuthRecordP2P)
-    {
-        NetworkInterfaceInfo *intf = FirstInterfaceForID(m, rr->resrec.InterfaceID);
-        if (!intf)
-        {
-            debugf("mDNS_Register_internal: Bogus InterfaceID %p in resource record", rr->resrec.InterfaceID);
-            return(mStatus_BadReferenceErr);
-        }
-    }
-
     rr->next = mDNSNULL;
 
     // Field Group 1: The actual information pertaining to this resource record
@@ -2821,7 +2810,8 @@ mDNSlocal void SendResponses(mDNS *const m)
         if (rr->SendRNow)
         {
             if (rr->ARType != AuthRecordLocalOnly && rr->ARType != AuthRecordP2P)
-                LogMsg("SendResponses: No active interface %p to send: %p %02X %s", rr->SendRNow, rr->resrec.InterfaceID, rr->resrec.RecordType, ARDisplayString(m, rr));
+                LogInfo("SendResponses: No active interface %d to send: %d %02X %s",
+                     (uint32_t)rr->SendRNow, (uint32_t)rr->resrec.InterfaceID, rr->resrec.RecordType, ARDisplayString(m, rr));
             rr->SendRNow = mDNSNULL;
         }
 
@@ -3467,6 +3457,11 @@ mDNSlocal void SendQueries(mDNS *const m)
             {
                 if (ar->AddressProxy.type == mDNSAddrType_IPv4)
                 {
+                       // There's a problem here. If a host is waking up, and we probe to see if it responds, then
+                       // it will see those ARP probes as signalling intent to use the address, so it picks a different one.
+                       // A more benign way to find out if a host is responding to ARPs might be send a standard ARP *request*
+                       // (using our sender IP address) instead of an ARP *probe* (using all-zero sender IP address).
+                       // A similar concern may apply to the NDP Probe too. -- SC
                     LogSPS("SendQueries ARP Probe %d %s %s", ar->ProbeCount, InterfaceNameForID(m, ar->resrec.InterfaceID), ARDisplayString(m,ar));
                     SendARP(m, 1, ar, &zerov4Addr, &zeroEthAddr, &ar->AddressProxy.ip.v4, &ar->WakeUp.IMAC);
                 }
@@ -3747,7 +3742,8 @@ mDNSlocal void SendQueries(mDNS *const m)
         if (ar->SendRNow)
         {
             if (ar->ARType != AuthRecordLocalOnly && ar->ARType != AuthRecordP2P)
-                LogMsg("SendQueries: No active interface %p to send probe: %p %s", ar->SendRNow, ar->resrec.InterfaceID, ARDisplayString(m, ar));
+                LogInfo("SendQueries: No active interface %d to send probe: %d %s",
+                    (uint32_t)ar->SendRNow, (uint32_t)ar->resrec.InterfaceID, ARDisplayString(m, ar));
             ar->SendRNow = mDNSNULL;
         }
 
@@ -3778,7 +3774,8 @@ mDNSlocal void SendQueries(mDNS *const m)
         {
             DNSQuestion *x;
             for (x = m->NewQuestions; x; x=x->next) if (x == q) break;  // Check if this question is a NewQuestion
-            LogMsg("SendQueries: No active interface %p to send %s question: %p %##s (%s)", q->SendQNow, x ? "new" : "old", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
+            LogInfo("SendQueries: No active interface %d to send %s question: %d %##s (%s)",
+                (uint32_t)q->SendQNow, x ? "new" : "old", (uint32_t)q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
             q->SendQNow = mDNSNULL;
         }
         q->CachedAnswerNeedsUpdate = mDNSfalse;
@@ -10347,6 +10344,7 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, void *const pkt, const mDNSu8 *co
 // (b) being performed by a unicast DNS long-lived query (either full LLQ, or polling)
 // for multicast questions, we don't want to treat LongLived as anything special
 #define IsLLQ(Q) ((Q)->LongLived && !mDNSOpaque16IsZero((Q)->TargetQID))
+#define IsAWDLIncluded(Q) (((Q)->flags & kDNSServiceFlagsIncludeAWDL) != 0)
 
 mDNSlocal DNSQuestion *FindDuplicateQuestion(const mDNS *const m, const DNSQuestion *const question)
 {
@@ -10369,6 +10367,7 @@ mDNSlocal DNSQuestion *FindDuplicateQuestion(const mDNS *const m, const DNSQuest
             (q->DisallowPID == question->DisallowPID)     &&            // Disallowing a PID should not affect a PID that is allowed
             (q->BrowseThreshold == question->BrowseThreshold) &&  // browse thresholds must match
             q->qnamehash  == question->qnamehash    &&
+            (IsAWDLIncluded(q) == IsAWDLIncluded(question)) &&  // Inclusion of AWDL interface must match
             SameDomainName(&q->qname, &question->qname))        // and name
             return(q);
     return(mDNSNULL);
@@ -11334,8 +11333,8 @@ mDNSlocal mStatus ValidateParameters(mDNS *const m, DNSQuestion *const question)
     {
         NetworkInterfaceInfo *intf = FirstInterfaceForID(m, question->InterfaceID);
         if (!intf)
-            LogMsg("ValidateParameters: Note: InterfaceID %p for question %##s (%s) not currently found in active interface list",
-                    question->InterfaceID, question->qname.c, DNSTypeName(question->qtype));
+            LogInfo("ValidateParameters: Note: InterfaceID %d for question %##s (%s) not currently found in active interface list",
+                    (uint32_t)question->InterfaceID, question->qname.c, DNSTypeName(question->qtype));
     }
     
     return(mStatus_NoError);
@@ -11445,9 +11444,15 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
     question->LOAddressAnswers  = 0;
     question->FlappingInterface1 = mDNSNULL;
     question->FlappingInterface2 = mDNSNULL;
-
-    question->ServiceID = mDNSPlatformGetServiceID(m, question);
-    
+       
+       // if kDNSServiceFlagsServiceIndex flag is SET by the client, then do NOT call mDNSPlatformGetServiceID()
+       // since we would already have the question->ServiceID in that case.
+       if (!(question->flags & kDNSServiceFlagsServiceIndex))
+               question->ServiceID = mDNSPlatformGetServiceID(m, question);
+       else
+               LogInfo("InitCommonState: Query for %##s (%s), PID[%d], ServiceID %d is already set by client", question->qname.c,
+                          DNSTypeName(question->qtype), question->pid, question->ServiceID);
+       
     InitDNSConfig(m, question);
 
     question->AuthInfo          = GetAuthInfoForQuestion(m, question);
@@ -11459,10 +11464,8 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
     // set DisallowPID
     question->DisallowPID       = (question->ServiceID == 0 || (mDNSPlatformAllowPID(m, question) == 0));
     if (question->DisallowPID)
-    {
         LogInfo("InitCommonState: Query suppressed for %##s (%s), PID %d/ServiceID %d not allowed", question->qname.c,
-            DNSTypeName(question->qtype), question->pid, question->ServiceID);
-    }
+                                       DNSTypeName(question->qtype), question->pid, question->ServiceID);
 
     question->NextInDQList      = mDNSNULL;
     question->SendQNow          = mDNSNULL;
@@ -11983,6 +11986,8 @@ mDNSlocal mStatus mDNS_StartBrowse_internal(mDNS *const m, DNSQuestion *const qu
     question->ForceMCast       = ForceMCast;
     question->ReturnIntermed   = mDNSfalse;
     question->SuppressUnusable = mDNSfalse;
+    question->DenyOnCellInterface = mDNSfalse;
+    question->DenyOnExpInterface  = mDNSfalse;
     question->SearchListIndex  = 0;
     question->AppendSearchDomains = 0;
     question->RetryWithSearchDomains = mDNSfalse;
@@ -12179,6 +12184,8 @@ mDNSexport mStatus mDNS_StartResolveService(mDNS *const m,
     query->qSRV.ForceMCast          = mDNSfalse;
     query->qSRV.ReturnIntermed      = mDNSfalse;
     query->qSRV.SuppressUnusable    = mDNSfalse;
+    query->qSRV.DenyOnCellInterface = mDNSfalse;
+    query->qSRV.DenyOnExpInterface  = mDNSfalse;
     query->qSRV.SearchListIndex     = 0;
     query->qSRV.AppendSearchDomains = 0;
     query->qSRV.RetryWithSearchDomains = mDNSfalse;
@@ -12205,6 +12212,8 @@ mDNSexport mStatus mDNS_StartResolveService(mDNS *const m,
     query->qTXT.ForceMCast          = mDNSfalse;
     query->qTXT.ReturnIntermed      = mDNSfalse;
     query->qTXT.SuppressUnusable    = mDNSfalse;
+    query->qTXT.DenyOnCellInterface = mDNSfalse;
+    query->qTXT.DenyOnExpInterface  = mDNSfalse;
     query->qTXT.SearchListIndex     = 0;
     query->qTXT.AppendSearchDomains = 0;
     query->qTXT.RetryWithSearchDomains = mDNSfalse;
@@ -12231,6 +12240,8 @@ mDNSexport mStatus mDNS_StartResolveService(mDNS *const m,
     query->qAv4.ForceMCast          = mDNSfalse;
     query->qAv4.ReturnIntermed      = mDNSfalse;
     query->qAv4.SuppressUnusable    = mDNSfalse;
+    query->qAv4.DenyOnCellInterface = mDNSfalse;
+    query->qAv4.DenyOnExpInterface  = mDNSfalse;
     query->qAv4.SearchListIndex     = 0;
     query->qAv4.AppendSearchDomains = 0;
     query->qAv4.RetryWithSearchDomains = mDNSfalse;
@@ -12257,6 +12268,8 @@ mDNSexport mStatus mDNS_StartResolveService(mDNS *const m,
     query->qAv6.ForceMCast          = mDNSfalse;
     query->qAv6.ReturnIntermed      = mDNSfalse;
     query->qAv6.SuppressUnusable    = mDNSfalse;
+    query->qAv6.DenyOnCellInterface = mDNSfalse;
+    query->qAv6.DenyOnExpInterface  = mDNSfalse;
     query->qAv6.SearchListIndex     = 0;
     query->qAv6.AppendSearchDomains = 0;
     query->qAv6.RetryWithSearchDomains = mDNSfalse;
@@ -12318,6 +12331,8 @@ mDNSexport mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, m
     question->ForceMCast       = mDNSfalse;
     question->ReturnIntermed   = mDNSfalse;
     question->SuppressUnusable = mDNSfalse;
+    question->DenyOnCellInterface = mDNSfalse;
+    question->DenyOnExpInterface  = mDNSfalse;
     question->SearchListIndex  = 0;
     question->AppendSearchDomains = 0;
     question->RetryWithSearchDomains = mDNSfalse;
@@ -12817,7 +12832,8 @@ mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *s
     if (set->Advertise)
         AdvertiseInterface(m, set);
 
-    LogInfo("mDNS_RegisterInterface: InterfaceID %p %s (%#a) %s", set->InterfaceID, set->ifname, &set->ip,
+    LogInfo("mDNS_RegisterInterface: InterfaceID %d %s (%#a) %s",
+            (uint32_t)set->InterfaceID, set->ifname, &set->ip,
             set->InterfaceActive ?
             "not represented in list; marking active and retriggering queries" :
             "already represented in list; marking inactive for now");
@@ -12961,8 +12977,8 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
         NetworkInterfaceInfo *intf = FirstInterfaceForID(m, set->InterfaceID);
         if (intf)
         {
-            LogInfo("mDNS_DeregisterInterface: Another representative of InterfaceID %p %s (%#a) exists;"
-                    " making it active", set->InterfaceID, set->ifname, &set->ip);
+            LogInfo("mDNS_DeregisterInterface: Another representative of InterfaceID %d %s (%#a) exists;"
+                    " making it active", (uint32_t)set->InterfaceID, set->ifname, &set->ip);
             if (intf->InterfaceActive)
                 LogMsg("mDNS_DeregisterInterface: ERROR intf->InterfaceActive already set for %s (%#a)", set->ifname, &set->ip);
             intf->InterfaceActive = mDNStrue;
@@ -12984,8 +13000,8 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
             CacheRecord *rr;
             DNSQuestion *q;
 
-            LogInfo("mDNS_DeregisterInterface: Last representative of InterfaceID %p %s (%#a) deregistered;"
-                    " marking questions etc. dormant", set->InterfaceID, set->ifname, &set->ip);
+            LogInfo("mDNS_DeregisterInterface: Last representative of InterfaceID %d %s (%#a) deregistered;"
+                    " marking questions etc. dormant", (uint32_t)set->InterfaceID, set->ifname, &set->ip);
 
             m->mDNSStats.InterfaceDown++;
 
index 81b4192b7fcc502c1239a806dfe48bc158ae26dd..bafeb0262c9aeecff568d9fbd3abd6818e6b3ca8 100755 (executable)
@@ -1983,10 +1983,12 @@ struct DNSQuestion_struct
     mDNSBool ForceMCast;                    // Set by client to force mDNS query, even for apparently uDNS names
     mDNSBool ReturnIntermed;                // Set by client to request callbacks for intermediate CNAME/NXDOMAIN results
     mDNSBool SuppressUnusable;              // Set by client to suppress unusable queries to be sent on the wire
+    mDNSBool DenyOnCellInterface;           // Set by client to suppress uDNS queries on cellular interface
+    mDNSBool DenyOnExpInterface;            // Set by client to suppress uDNS queries on expensive interface
     mDNSu8 RetryWithSearchDomains;          // Retry with search domains if there is no entry in the cache or AuthRecords
     mDNSu8 TimeoutQuestion;                 // Timeout this question if there is no reply in configured time
     mDNSu8 WakeOnResolve;                   // Send wakeup on resolve
-    mDNSu8 UseBackgroundTrafficClass;       // Use background traffic class for request
+    mDNSu8 UseBackgroundTrafficClass;       // Set by client to use background traffic class for request
     mDNSs8 SearchListIndex;                 // Index into SearchList; Used by the client layer but not touched by core
     mDNSs8 AppendSearchDomains;             // Search domains can be appended for this query
     mDNSs8 AppendLocalSearchDomains;        // Search domains ending in .local can be appended for this query
@@ -3336,7 +3338,7 @@ extern void mDNSPlatformSleepAssertion(mDNS *const m, double timeout);
 
 extern mDNSBool mDNSPlatformAllowPID(mDNS *const m, DNSQuestion *q);
 extern mDNSs32 mDNSPlatformGetServiceID(mDNS *const m, DNSQuestion *q);
-extern void mDNSPlatformSetDelegatePID(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q);
+extern void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q);
 extern mDNSs32 mDNSPlatformGetPID(void);
 
 // ***************************************************************************
index 8c7c3300506fbb9757d5fddfcefa5dd9dab13008..ce12d01ac2724067df6ae19e5d0c863edf1e3eef 100755 (executable)
@@ -1880,6 +1880,8 @@ mDNSlocal mStatus GetZoneData_StartQuery(mDNS *const m, ZoneData *zd, mDNSu16 qt
     zd->question.ForceMCast          = mDNSfalse;
     zd->question.ReturnIntermed      = mDNStrue;
     zd->question.SuppressUnusable    = mDNSfalse;
+    zd->question.DenyOnCellInterface = mDNSfalse;
+    zd->question.DenyOnExpInterface  = mDNSfalse;
     zd->question.SearchListIndex     = 0;
     zd->question.AppendSearchDomains = 0;
     zd->question.RetryWithSearchDomains = mDNSfalse;
@@ -2567,6 +2569,8 @@ mDNSlocal void GetStaticHostname(mDNS *m)
     q->ForceMCast       = mDNSfalse;
     q->ReturnIntermed   = mDNStrue;
     q->SuppressUnusable = mDNSfalse;
+    q->DenyOnCellInterface = mDNSfalse;
+    q->DenyOnExpInterface  = mDNSfalse;
     q->SearchListIndex  = 0;
     q->AppendSearchDomains = 0;
     q->RetryWithSearchDomains = mDNSfalse;
@@ -4791,7 +4795,7 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
                     {
                         q->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
                         if (q->LocalSocket)
-                            mDNSPlatformSetDelegatePID(q->LocalSocket, &q->qDNSServer->addr, q);
+                            mDNSPlatformSetuDNSSocktOpt(q->LocalSocket, &q->qDNSServer->addr, q);
                     }
                     if (!q->LocalSocket) err = mStatus_NoMemoryErr; // If failed to make socket (should be very rare), we'll try again next time
                     else err = mDNSSendDNSMessage(m, &m->omsg, end, q->qDNSServer->interface, q->LocalSocket, &q->qDNSServer->addr, q->qDNSServer->port, mDNSNULL, mDNSNULL, q->UseBackgroundTrafficClass);
index 434e65cdba9bee760cc20be7d0ec2ec8d3f6f5ae..187748e1ca11ea3ffe921c1eba087489f75c06cb 100644 (file)
@@ -52,18 +52,22 @@ mDNSexport mDNSBool mDNSPlatformAllowPID(mDNS *const m, DNSQuestion *q)
         }
         else
         {
-            allowed = (mDNSBool) cellular_usage_policy_is_data_allowed_for_uuid(m->p->handle, q->uuid);
-            if (!allowed)
-            {
-                xpc_object_t uuidx = xpc_uuid_create(q->uuid);
-                if (uuidx)
-                {
-                    network_config_cellular_blocked_notify(NULL, uuidx, NULL);
-                    LogInfo("mDNSPlaformAllowPID: Notified UUID for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
-                    xpc_release(uuidx);
-                }
-            }
-        }
+           xpc_object_t uuidx = xpc_uuid_create(q->uuid);
+           if (uuidx)
+           {
+               allowed = (mDNSBool) cellular_usage_policy_is_data_allowed_for_uuid(m->p->handle, uuidx);
+               if (!allowed)
+               {
+                   network_config_cellular_blocked_notify(NULL, uuidx, NULL);
+                   LogInfo("mDNSPlaformAllowPID: Notified UUID for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+               }
+               xpc_release(uuidx);
+           }
+           else
+           {
+               allowed = false;
+           }
+       }
         return allowed;
     }
     else
index a21868c7515e4a9f9e2b61aa9d6624240bf4adcc..09b61e08aa17457cb9b3998978074aa567c00f8c 100644 (file)
@@ -3,7 +3,7 @@
 <plist version="1.0">
 <dict>
   <key>Label</key>
-  <string>com.apple.mDNSResponderHelper</string>
+  <string>com.apple.mDNSResponderHelper.reloaded</string>
   <key>OnDemand</key>
   <true/>
   <key>ProgramArguments</key>
index c1fe89a303d799d1acc49fbb35610934d7011cf4..4226c7956a84937c3c7c1420303666481b3d1c7d 100644 (file)
@@ -3,9 +3,7 @@
 <plist version="1.0">
 <dict>
        <key>Label</key>
-       <string>com.apple.networking.mDNSResponder</string>
-    <key>Disabled</key>
-    <true/>
+       <string>com.apple.mDNSResponder.reloaded</string>
        <key>OnDemand</key>
        <false/>
        <key>InitGroups</key>
index a14d686cb09726a241486ef76f5a83d423821abe..1df3b21df73bf808098701ee4730d783325786f1 100644 (file)
@@ -6,7 +6,7 @@
  * Resides in /usr/lib/libdns_services.dylib
  */
 
-#include "dns_services_mdns.h"
+#include "dns_services.h"
 #include "dns_xpc.h"
 #include <xpc/xpc.h>
 #include <Block.h>
diff --git a/mDNSMacOSX/Private/dns_services.h b/mDNSMacOSX/Private/dns_services.h
new file mode 100644 (file)
index 0000000..7b74e10
--- /dev/null
@@ -0,0 +1,124 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ *
+ * @header      Interface to DNSX SPI
+ *
+ * @discussion  Describes the functions and data structures
+ *              that make up the DNSX SPI
+ */
+
+#ifndef _DNS_SERVICES_H
+#define _DNS_SERVICES_H
+
+#include <dispatch/dispatch.h>
+
+// DNSXConnRef: Opaque internal data type
+typedef struct _DNSXConnRef_t *DNSXConnRef;
+
+typedef enum
+{
+    kDNSX_NoError                   =  0,
+    kDNSX_UnknownErr                = -65537,   /* 0xFFFE FFFF */
+    kDNSX_NoMem                     = -65539,
+    kDNSX_BadParam                  = -65540,
+    kDNSX_DaemonNotRunning          = -65563,   /* Background daemon not running */
+    kDNSX_DictError                 = -65565,   /* Dictionary Error */
+    kDNSX_Engaged                   = -65566,   /* DNS Proxy is in use by another client */
+    kDNSX_Timeout                   = -65568    
+} DNSXErrorType;
+
+// A max of 5 input interfaces can be processed at one time
+#define MaxInputIf 5
+#define IfIndex uint64_t
+#define kDNSIfindexAny 0
+
+// Enable DNS Proxy with an appropriate parameter defined below
+typedef enum
+{
+    kDNSProxyEnable = 1
+    // Other values reserved for future use
+} DNSProxyParameters;
+
+/*********************************************************************************************
+*
+*  Enable DNS Proxy Functionality
+*
+*********************************************************************************************/
+
+/* DNSXEnableProxy : Turns ON the DNS Proxy (Details below)
+ *
+ * DNSXEnableProxyReply() parameters:
+ *
+ * connRef:                  The DNSXConnRef initialized by DNSXEnableProxy().
+ *
+ * errCode:                  Will be kDNSX_NoError on success, otherwise will indicate the 
+ *                           failure that occurred.  Other parameters are undefined if 
+ *                           errCode is nonzero.
+ *
+ */
+
+typedef void (*DNSXEnableProxyReply)
+(
+    DNSXConnRef           connRef,
+    DNSXErrorType         errCode 
+);
+
+/* DNSXEnableProxy
+ * 
+ * Enables the DNS Proxy functionality which will remain ON until the client terminates explictly (or exits/crashes).
+ * Client can turn it OFF by passing the returned DNSXConnRef to DNSXRefDeAlloc()
+ * 
+ * DNSXEnableProxy() Parameters:
+ *
+ * connRef:                   A pointer to DNSXConnRef that is initialized to NULL when called for the first  
+ *                            time. If the call succeeds it will be initialized to a non-NULL value.
+ *                            Client terminates the DNS Proxy by passing this DNSXConnRef to DNSXRefDeAlloc().
+ *
+ * proxyparam:                Enable DNS Proxy functionality with parameters that are described in
+ *                            DNSProxyParameters above.
+ *
+ * inIfindexArr[MaxInputIf]:  List of input interfaces from which the DNS queries will be accepted and
+ *                            forwarded to the output interface specified below. The daemon processes
+ *                            MaxInputIf entries in the list. For eg. if one has less than MaxInputIfs
+ *                            values, just initialize the other values to be 0. Note: This field needs to
+ *                            be initialized by the client.
+ *
+ * outIfindex:                Output interface on which the query will be forwarded.
+ *                            Passing kDNSIfindexAny causes DNS Queries to be sent on the primary interface.
+ *
+ * clientq:                   Queue the client wants to schedule the callBack on (Note: Must not be NULL)
+ *
+ * callBack:                  CallBack function for the client that indicates success or failure.
+ *                            Note: callback may be invoked more than once, For eg. if enabling DNS Proxy
+ *                            first succeeds and the daemon possibly crashes sometime later. 
+ *
+ * return value:              Returns kDNSX_NoError when no error otherwise returns an error code indicating
+ *                            the error that occurred. Note: A return value of kDNSX_NoError does not mean 
+ *                            that DNS Proxy was successfully enabled. The callBack may asynchronously
+ *                            return an error (such as kDNSX_DaemonNotRunning/ kDNSX_Engaged)
+ *
+ */
+
+DNSXErrorType DNSXEnableProxy
+(
+    DNSXConnRef              *connRef,
+    DNSProxyParameters       proxyparam,
+    IfIndex                  inIfindexArr[MaxInputIf],
+    IfIndex                  outIfindex,
+    dispatch_queue_t         clientq,
+    DNSXEnableProxyReply     callBack
+);
+
+/* DNSXRefDeAlloc()
+ *
+ * Terminate a connection with the daemon and free memory associated with the DNSXConnRef.
+ * Used to Disable DNS Proxy on that connection.
+ *
+ * connRef:        A DNSXConnRef initialized by any of the DNSX*() calls.
+ *
+ */
+void DNSXRefDeAlloc(DNSXConnRef connRef);
+
+#endif  /* _DNS_SERVICES_H */
diff --git a/mDNSMacOSX/Private/dns_services_mdns.h b/mDNSMacOSX/Private/dns_services_mdns.h
deleted file mode 100644 (file)
index 7b74e10..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2012 Apple Inc. All rights reserved.
- *
- *
- * @header      Interface to DNSX SPI
- *
- * @discussion  Describes the functions and data structures
- *              that make up the DNSX SPI
- */
-
-#ifndef _DNS_SERVICES_H
-#define _DNS_SERVICES_H
-
-#include <dispatch/dispatch.h>
-
-// DNSXConnRef: Opaque internal data type
-typedef struct _DNSXConnRef_t *DNSXConnRef;
-
-typedef enum
-{
-    kDNSX_NoError                   =  0,
-    kDNSX_UnknownErr                = -65537,   /* 0xFFFE FFFF */
-    kDNSX_NoMem                     = -65539,
-    kDNSX_BadParam                  = -65540,
-    kDNSX_DaemonNotRunning          = -65563,   /* Background daemon not running */
-    kDNSX_DictError                 = -65565,   /* Dictionary Error */
-    kDNSX_Engaged                   = -65566,   /* DNS Proxy is in use by another client */
-    kDNSX_Timeout                   = -65568    
-} DNSXErrorType;
-
-// A max of 5 input interfaces can be processed at one time
-#define MaxInputIf 5
-#define IfIndex uint64_t
-#define kDNSIfindexAny 0
-
-// Enable DNS Proxy with an appropriate parameter defined below
-typedef enum
-{
-    kDNSProxyEnable = 1
-    // Other values reserved for future use
-} DNSProxyParameters;
-
-/*********************************************************************************************
-*
-*  Enable DNS Proxy Functionality
-*
-*********************************************************************************************/
-
-/* DNSXEnableProxy : Turns ON the DNS Proxy (Details below)
- *
- * DNSXEnableProxyReply() parameters:
- *
- * connRef:                  The DNSXConnRef initialized by DNSXEnableProxy().
- *
- * errCode:                  Will be kDNSX_NoError on success, otherwise will indicate the 
- *                           failure that occurred.  Other parameters are undefined if 
- *                           errCode is nonzero.
- *
- */
-
-typedef void (*DNSXEnableProxyReply)
-(
-    DNSXConnRef           connRef,
-    DNSXErrorType         errCode 
-);
-
-/* DNSXEnableProxy
- * 
- * Enables the DNS Proxy functionality which will remain ON until the client terminates explictly (or exits/crashes).
- * Client can turn it OFF by passing the returned DNSXConnRef to DNSXRefDeAlloc()
- * 
- * DNSXEnableProxy() Parameters:
- *
- * connRef:                   A pointer to DNSXConnRef that is initialized to NULL when called for the first  
- *                            time. If the call succeeds it will be initialized to a non-NULL value.
- *                            Client terminates the DNS Proxy by passing this DNSXConnRef to DNSXRefDeAlloc().
- *
- * proxyparam:                Enable DNS Proxy functionality with parameters that are described in
- *                            DNSProxyParameters above.
- *
- * inIfindexArr[MaxInputIf]:  List of input interfaces from which the DNS queries will be accepted and
- *                            forwarded to the output interface specified below. The daemon processes
- *                            MaxInputIf entries in the list. For eg. if one has less than MaxInputIfs
- *                            values, just initialize the other values to be 0. Note: This field needs to
- *                            be initialized by the client.
- *
- * outIfindex:                Output interface on which the query will be forwarded.
- *                            Passing kDNSIfindexAny causes DNS Queries to be sent on the primary interface.
- *
- * clientq:                   Queue the client wants to schedule the callBack on (Note: Must not be NULL)
- *
- * callBack:                  CallBack function for the client that indicates success or failure.
- *                            Note: callback may be invoked more than once, For eg. if enabling DNS Proxy
- *                            first succeeds and the daemon possibly crashes sometime later. 
- *
- * return value:              Returns kDNSX_NoError when no error otherwise returns an error code indicating
- *                            the error that occurred. Note: A return value of kDNSX_NoError does not mean 
- *                            that DNS Proxy was successfully enabled. The callBack may asynchronously
- *                            return an error (such as kDNSX_DaemonNotRunning/ kDNSX_Engaged)
- *
- */
-
-DNSXErrorType DNSXEnableProxy
-(
-    DNSXConnRef              *connRef,
-    DNSProxyParameters       proxyparam,
-    IfIndex                  inIfindexArr[MaxInputIf],
-    IfIndex                  outIfindex,
-    dispatch_queue_t         clientq,
-    DNSXEnableProxyReply     callBack
-);
-
-/* DNSXRefDeAlloc()
- *
- * Terminate a connection with the daemon and free memory associated with the DNSXConnRef.
- * Used to Disable DNS Proxy on that connection.
- *
- * connRef:        A DNSXConnRef initialized by any of the DNSX*() calls.
- *
- */
-void DNSXRefDeAlloc(DNSXConnRef connRef);
-
-#endif  /* _DNS_SERVICES_H */
index 8c1bf1d05a60694f01b1404d4131bbe6fbccf99e..623ddbf437384fb87c19a0de49413cff13b518aa 100644 (file)
@@ -23,13 +23,11 @@ mDNSexport mDNSs32 mDNSPlatformGetServiceID(mDNS *const m, DNSQuestion *q)
     int sid;
 
     if (q->pid)
-    {
         sid = VPNAppLayerGetMatchingServiceIdentifier(q->pid, NULL);
-    }
     else
-    {
         sid = VPNAppLayerGetMatchingServiceIdentifier(0, q->uuid);
-    }
+    
     LogInfo("mDNSPlatformGetServiceID: returning %d for %##s (%s)", sid, q->qname.c, DNSTypeName(q->qtype));
+    
     return sid;
 }
index acdb68fbc4bd2e5be30fe37141f328d4c75aab61..1b257ea21fbbb8cb6301c36814ba395269debe77 100644 (file)
@@ -2474,10 +2474,9 @@ mDNSlocal mDNSBool AllowSleepNow(mDNS *const m, mDNSs32 now)
         }
 
         m->SleepState = SleepState_Sleeping;
-        // We used to clear our interface list to empty state here before going to sleep.
-        // The applications that try to connect to an external server during maintenance wakes, saw
-        // DNS resolution errors as we don't have any interfaces (most queries use SuppressUnusable
-        // flag). Thus, we don't remove our interfaces anymore on sleep.
+               // Clear our interface list to empty state, ready to go to sleep
+               // As a side effect of doing this, we'll also cancel any outstanding SPS Resolve calls that didn't complete
+        mDNSMacOSXNetworkChanged(m);
     }
 
     LogSPS("AllowSleepNow: %s(%lX) %s at %ld (%d ticks remaining)",
index 28d73f63f8d83d8b46e1b5e75a6f0101a3e9a9b3..f904c8b22f8cfe9d7c0c282329f33a9b8cec213c 100644 (file)
@@ -115,7 +115,6 @@ D2DStatus D2DTerminate() __attribute__((weak_import));
 #include <IOKit/platform/IOPlatformSupportPrivate.h>
 #endif // APPLE_OSX_mDNSResponder && !TARGET_OS_EMBEDDED
 
-
 #define kInterfaceSpecificOption "interface="
 
 #define mDNS_IOREG_KEY               "mDNS_KEY"
@@ -1037,7 +1036,13 @@ mDNSexport void external_stop_resolving_service(const domainname *const fqdn, DN
 // 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.
+
+// We also don't want to use multicast on *any* interface on very constrained devices.
+#if TARGET_OS_NANO
+#define MulticastInterface(i) (mDNSfalse)
+#else
 #define MulticastInterface(i) (((i)->ifa_flags & IFF_MULTICAST) && !((i)->ifa_flags & IFF_POINTOPOINT))
+#endif
 
 mDNSexport void NotifyOfElusiveBug(const char *title, const char *msg)  // Both strings are UTF-8 text
 {
@@ -1692,35 +1697,56 @@ mDNSlocal void setTrafficClass(int socketfd, mDNSBool useBackgroundTrafficClass)
     (void) setsockopt(socketfd, SOL_SOCKET, SO_TRAFFIC_CLASS, (void *)&traffic_class, sizeof(traffic_class));
 }
 
-mDNSexport void mDNSPlatformSetDelegatePID(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q)
+mDNSexport void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q)
 {
     if (src)
     {
         int s;
 
         if (dst->type == mDNSAddrType_IPv4)
-        {
             s = src->ss.sktv4;
-        }
         else
-        {
             s = src->ss.sktv6;
-        }
 
         if (q->pid)
         {
             if (setsockopt(s, SOL_SOCKET, SO_DELEGATED, &q->pid, sizeof(q->pid)) == -1)
-            {
-                LogInfo("mDNSPlatformSetDelegatePID: Delegate PID failed %s for PID %d", strerror(errno), q->pid);
-            }
+                LogInfo("mDNSPlatformSetuDNSSocktOpt: Delegate PID failed %s for PID %d", strerror(errno), q->pid);
         }
         else
         {
             if (setsockopt(s, SOL_SOCKET, SO_DELEGATED_UUID, &q->uuid, sizeof(q->uuid)) == -1)
+                LogInfo("mDNSPlatformSetuDNSSocktOpt: Delegate UUID failed %s", strerror(errno));
+        }
+               
+#if defined(SO_NOWAKEFROMSLEEP)
+        int nowake = 1;
+        if (setsockopt(s, SOL_SOCKET, SO_NOWAKEFROMSLEEP, &nowake, sizeof(nowake)) == -1)
+            LogInfo("mDNSPlatformSetuDNSSocktOpt: SO_NOWAKEFROMSLEEP failed %s", strerror(errno));
+#endif
+       
+        if (q->DenyOnCellInterface || q->DenyOnExpInterface)
+        {
+#if defined(SO_RESTRICT_DENY_CELLULAR)
+            if (q->DenyOnCellInterface)
             {
-                LogInfo("mDNSPlatformSetDelegatePID: Delegate UUID failed %s", strerror(errno));
+                int restrictions = 0;
+                restrictions = SO_RESTRICT_DENY_CELLULAR;
+                if (setsockopt(s, SOL_SOCKET, SO_RESTRICTIONS, &restrictions, sizeof(restrictions)) == -1)
+                    LogInfo("mDNSPlatformSetuDNSSocktOpt: SO_RESTRICT_DENY_CELLULAR failed %s", strerror(errno));
             }
-        }
+#endif
+#if defined(SO_RESTRICT_DENY_EXPENSIVE)
+            if (q->DenyOnExpInterface)
+            {
+                int restrictions = 0;
+                restrictions = SO_RESTRICT_DENY_EXPENSIVE;
+                if (setsockopt(s, SOL_SOCKET, SO_RESTRICTIONS, &restrictions, sizeof(restrictions)) == -1)
+                    LogInfo("mDNSPlatformSetuDNSSocktOpt: SO_RESTRICT_DENY_EXPENSIVE failed %s", strerror(errno));
+            }
+#endif
+               }
+               
     }
 }
 
@@ -5164,6 +5190,8 @@ mDNSexport void AddNewClientTunnel(mDNS *const m, DNSQuestion *const q)
     p->q.ForceMCast       = mDNSfalse;
     p->q.ReturnIntermed   = mDNStrue;
     p->q.SuppressUnusable = mDNSfalse;
+    p->q.DenyOnCellInterface = mDNSfalse;
+    p->q.DenyOnExpInterface  = mDNSfalse;
     p->q.SearchListIndex  = 0;
     p->q.AppendSearchDomains = 0;
     p->q.RetryWithSearchDomains = mDNSfalse;
@@ -5202,6 +5230,8 @@ mDNSlocal mStatus UpdateInterfaceList(mDNS *const m, mDNSs32 utc)
     if (InfoSocket < 3 && errno != EAFNOSUPPORT) 
         LogMsg("UpdateInterfaceList: InfoSocket error %d errno %d (%s)", InfoSocket, errno, strerror(errno));
 
+    if (m->SleepState == SleepState_Sleeping) ifa = NULL;
+
     while (ifa)
     {
 #if LIST_ALL_INTERFACES
@@ -7910,13 +7940,16 @@ mDNSexport void mDNSMacOSXNetworkChanged(mDNS *const m)
 }
 
 // Called with KQueueLock & mDNS lock
+// SetNetworkChanged is allowed to extend (but not reduce) the pause while we wait for configuration changes to settle
 mDNSlocal void SetNetworkChanged(mDNS *const m, mDNSs32 delay)
 {
     if (!m->p->NetworkChanged || m->p->NetworkChanged - NonZeroTime(m->timenow + delay) < 0)
     {
         m->p->NetworkChanged = NonZeroTime(m->timenow + delay);
-        LogInfo("SetNetworkChanged: scheduling in %d msec", delay);
+        LogInfo("SetNetworkChanged: Scheduling in %d msec", delay);
     }
+    else
+        LogInfo("SetNetworkChanged: *NOT* reducing delay from %d to %d", m->p->NetworkChanged - m->timenow, delay);
 }
 
 // Called with KQueueLock & mDNS lock
@@ -7948,7 +7981,7 @@ mDNSlocal CFStringRef CopyNameFromKey(CFStringRef key)
 
 // 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)
+mDNSlocal int ChangedKeysHaveIPv4LL(CFArrayRef inkeys)
 {
     SCDynamicStoreRef store = NULL;
     CFDictionaryRef dict = NULL;
@@ -7956,7 +7989,7 @@ mDNSlocal mDNSBool ChangedKeysHaveIPv4LL(CFArrayRef inkeys)
     const void **keys = NULL, **vals = NULL;
     CFStringRef pattern = NULL;
     int i, ic, j, jc;
-    mDNSBool found = mDNSfalse;
+    int found = 0;
 
     jc = CFArrayGetCount(inkeys);
     if (!jc) goto done;
@@ -7993,7 +8026,8 @@ mDNSlocal mDNSBool ChangedKeysHaveIPv4LL(CFArrayRef inkeys)
     keys = mDNSPlatformMemAllocate(sizeof (void *) * ic);
     CFDictionaryGetKeysAndValues(dict, keys, vals);
 
-    for (j = 0; j < jc && !found; j++)
+    // For each key we were given...
+    for (j = 0; j < jc; j++)
     {
         CFStringRef key = CFArrayGetValueAtIndex(inkeys, j);
         CFStringRef ifname = NULL;
@@ -8010,6 +8044,7 @@ mDNSlocal mDNSBool ChangedKeysHaveIPv4LL(CFArrayRef inkeys)
             LogInfo("ChangedKeysHaveIPv4LL: potential ifname %s", buf);
         }
 
+        // Loop over the interfaces to find matching the ifname, and see if that one has kSCValNetIPv4ConfigMethodLinkLocal
         for (i = 0; i < ic; i++)
         {
             CFDictionaryRef ipv4dict;
@@ -8049,7 +8084,7 @@ mDNSlocal mDNSBool ChangedKeysHaveIPv4LL(CFArrayRef inkeys)
                 LogInfo("ChangedKeysHaveIPv4LL: configmethod %s", buf);
             }
 
-            if (CFEqual(configmethod, kSCValNetIPv4ConfigMethodLinkLocal)) { found = mDNStrue; break; }
+            if (CFEqual(configmethod, kSCValNetIPv4ConfigMethodLinkLocal)) { found++; break; }
         }
 
         CFRelease(ifname);
@@ -8067,7 +8102,6 @@ done:
 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);
@@ -8078,10 +8112,11 @@ mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, v
     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 c3 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_DNS         ) != 0);
+    int c4 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_DynamicDNS  ) != 0);
+    int c5 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_BackToMyMac ) != 0);
+    int c6 = ChangedKeysHaveIPv4LL(changedKeys);
+    int c7 = 0;
 
     // Do immediate network changed processing for "p2p*" interfaces and
     // for interfaces with the IFEF_DIRECTLINK flag set.
@@ -8116,8 +8151,8 @@ mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, v
                 if (CFStringGetCString(CFArrayGetValueAtIndex(labels, 3), buf, sizeof(buf), kCFStringEncodingUTF8)
                     && (strstr(buf, "p2p") || (getExtendedFlags(buf) & IFEF_DIRECTLINK)))
                 {
-                    LogInfo("NetworkChanged: interface %s, not delaying network change", buf);
-                    changeNow = mDNStrue;
+                    LogInfo("NetworkChanged: interface %s qualifies for reduced change handling delay", buf);
+                    c7++;
                     CFRelease(labels);
                     break;
                 }
@@ -8126,8 +8161,22 @@ mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, v
         }
     }
 
-    mDNSBool btmmChanged = CFArrayContainsValue(changedKeys, range, NetworkChangedKey_BackToMyMac);
-    if (btmmChanged) delay = 0;
+    if (c && c - c1 - c2 - c3 - c4 - c5 - c6 - c7 == 0)
+        delay = mDNSPlatformOneSecond/10;  // If these were the only changes, shorten delay
+
+    // Immediately force a reconfig (esp. cache flush) if any of the following is true:
+    // 1. DNS Settings changed.
+    // 2  An interface changed that is explicitly IPv4 link local
+    // 3. There are P2P/IFEF_DIRECTLINK/IsCarPlaySSID changes
+    if (c3 || ChangedKeysHaveIPv4LL(changedKeys) || c7)
+    {
+        LogInfo("NetworkChanged: %s : Handling this change immediately",
+                c3 ? "DNS Settings Changed" :
+                c7 ? "P2P/IFEF_DIRECTLINK/IsCarPlaySSID Changed" :
+                "An interface changed that is explicitly IPv4 link local");
+        m->p->NetworkChanged = NonZeroTime(m->timenow);
+        delay = 0; // for the logs below.
+    }
 
     if (mDNS_LoggingEnabled)
     {
@@ -8138,32 +8187,31 @@ mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, v
             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",
+        LogInfo("***   NetworkChanged   *** %d change%s %s%s%s%s%s%s%sdelay %d%s",
                 c, c>1 ? "s" : "",
                 c1 ? "(Local Hostname) " : "",
                 c2 ? "(Computer Name) "  : "",
-                c3 ? "(DynamicDNS) "     : "",
-                c4 ? "(DNS) "            : "",
-                changeNow ? 0 : delay);
+                c3 ? "(DNS) "            : "",
+                c4 ? "(DynamicDNS) "     : "",
+                c5 ? "(BTMM) "           : "",
+                c6 ? "(kSCValNetIPv4ConfigMethodLinkLocal) " : "",
+                c7 ? "(P2P/IFEF_DIRECTLINK/IsCarPlaySSID) "  : "",
+                delay,
+                (c4 || c5) ? " + SetKeyChainTimer" : "");
     }
 
-    if (!changeNow)
-        SetNetworkChanged(m, delay);
+    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)
+    if (c4 || c5)
         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");
 }
 
@@ -8781,9 +8829,7 @@ mDNSlocal void PowerChanged(void *refcon, io_service_t service, natural_t messag
         // 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);
+        SetNetworkChanged(m, mDNSPlatformOneSecond * 2);
         mDNS_Unlock(m);
 
         break;
@@ -8839,13 +8885,16 @@ mDNSlocal void SnowLeopardPowerChanged(void *refcon, IOPMConnection connection,
             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);
+        if (m->SleepState != SleepState_Awake)
+        {
+                       PowerOn(m);
+                       // 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, mDNSPlatformOneSecond * 2);
+                       mDNS_Unlock(m);
+        }
         IOPMConnectionAcknowledgeEvent(connection, token);
     }
     else
@@ -10415,9 +10464,37 @@ mDNSexport void mDNSPlatformDispatchAsync(mDNS *const m, void *context, AsyncDis
 #define OSX_VER_LEN     strlen(OSX_VER) 
 #define VER_NUM_LEN     2  // 2 digits of version number added to base string
 
+#define MODEL_COLOR           "ecolor="
+#define MODEL_COLOR_LEN       strlen(MODEL_COLOR)
+#define MODEL_RGB_VALUE_LEN   strlen("255,255,255") // 'r,g,b'
+
 // Bytes available in TXT record for model name after subtracting space for other 
 // fixed size strings and their length bytes.
-#define MAX_MODEL_NAME_LEN   (256 - (DEVINFO_MODEL_LEN + 1) - (OSX_VER_LEN + VER_NUM_LEN + 1))
+#define MAX_MODEL_NAME_LEN   (256 - (DEVINFO_MODEL_LEN + 1) - (OSX_VER_LEN + VER_NUM_LEN + 1) - (MODEL_COLOR_LEN + MODEL_RGB_VALUE_LEN + 1))
+
+mDNSlocal mDNSBool getModelIconColors(char *color)
+{
+       mDNSBool hasColor = mDNSfalse;
+       mDNSPlatformMemZero(color, MODEL_RGB_VALUE_LEN + 1);
+       
+#if !TARGET_OS_EMBEDDED && defined(kIOPlatformDeviceEnclosureColorKey)
+       mDNSu8   red      = 0;
+       mDNSu8   green    = 0;
+       mDNSu8   blue     = 0;
+
+       IOReturn rGetDeviceColor = IOPlatformGetDeviceColor(kIOPlatformDeviceEnclosureColorKey,
+                                                                                                               &red, &green, &blue);
+       if (kIOReturnSuccess == rGetDeviceColor)
+       {
+               // IOKit was able to get enclosure color for the current device.
+               hasColor = true;
+               snprintf(color, MODEL_RGB_VALUE_LEN + 1, "%d,%d,%d", red, green, blue);
+       }
+#endif // !TARGET_OS_EMBEDDED && defined(kIOPlatformDeviceEnclosureColorKey)
+       
+       return hasColor;
+}
+
 
 // Initialize device-info TXT record contents and return total length of record data.
 mDNSexport mDNSu32 initializeDeviceInfoTXT(mDNS *m, mDNSu8 *ptr)
@@ -10444,7 +10521,24 @@ mDNSexport mDNSu32 initializeDeviceInfoTXT(mDNS *m, mDNSu8 *ptr)
         snprintf(ver_num, VER_NUM_LEN + 1, "%d", OSXVers);
         mDNSPlatformMemCopy(ptr, ver_num, VER_NUM_LEN);
         ptr += VER_NUM_LEN;
+               
+               char rgb[MODEL_RGB_VALUE_LEN + 1]; // RGB value + null written by snprintf
+               if (getModelIconColors(rgb))
+               {
+                       len = strlen(rgb);
+                       *ptr = MODEL_COLOR_LEN + len; // length byte
+                       ptr++;
+               
+                       mDNSPlatformMemCopy(ptr, MODEL_COLOR, MODEL_COLOR_LEN);
+                       ptr += MODEL_COLOR_LEN;
+                       
+                       mDNSPlatformMemCopy(ptr, rgb, len);
+                       ptr += len;
+               }
     }
 
     return (ptr - bufferStart);
 }
+
+
+
index bb3f05e853f815b2a6cf3d6187f58504f503dfd9..21a343f898e04eec9a7c1408374a551bb1ae5d54 100644 (file)
     <true/>
     <key>com.apple.telephony.cupolicy-monitor-access</key>
     <true/>
+    <key>com.apple.private.necp.match</key>
+    <true/>
+    <key>com.apple.security.network.server</key>
+    <true/>
+    <key>com.apple.security.network.client</key>
+    <true/>
+    <key>com.apple.private.network.awdl.restricted</key>
+    <true/>
 </dict>
 </plist>
index eee623c81a70cb59e9a72cecc501165268eded72..f267f3242716d14b8d0d8e749b0f492d4a4432c8 100644 (file)
@@ -46,6 +46,7 @@
 ; These are needed for things like getpwnam, hostname changes, & keychain
 (allow mach-lookup
        (global-name "com.apple.bsd.dirhelper")
+       (global-name "com.apple.CoreServices.coreservicesd")
        (global-name "com.apple.distributed_notifications.2")
        (global-name "com.apple.ocspd")
        (global-name "com.apple.PowerManagement.control")
        (regex #"^/private/var/folders/[^/]+/[^/]+/C/mds(/|$)")
 
        ; Required on 10.5 and 10.6
-       (regex #"^/private/var/folders/[^/]+/[^/]+/-Caches-/mds(/|$)"))
+       (regex #"^/private/var/folders/[^/]+/[^/]+/-Caches-/mds(/|$)")
+
+       ; Required on 10.10.4
+       (regex #"^/private/var/folders/[^/]+/[^/]+/[0-9]+(/|$)"))
 
 ; CRL Cache for SSL/TLS connections
 (allow file-read-data (literal "/private/var/db/crls/crlcache.db"))
index 7831e19c5b0e02148823769450c18ff9542b35d6..39d8a45115f711d95da25433f57a891e099f4de4 100644 (file)
                        isa = PBXAggregateTarget;
                        buildConfigurationList = 03067D730C83A3CB0022BE1F /* Build configuration list for PBXAggregateTarget "Build Some" */;
                        buildPhases = (
+                               FF045B6A0C7E4AA600448140 /* ShellScript */,
                        );
                        dependencies = (
                                217A4C49138EE14C000A5BA8 /* PBXTargetDependency */,
+                               03067D680C83A3830022BE1F /* PBXTargetDependency */,
+                               03067D6A0C83A3890022BE1F /* PBXTargetDependency */,
                                03067D6C0C83A3920022BE1F /* PBXTargetDependency */,
+                               03067D6E0C83A39C0022BE1F /* PBXTargetDependency */,
                                84C5B3411665544B00C324A8 /* PBXTargetDependency */,
+                               BD7833F01ABA5E3500EC51ED /* PBXTargetDependency */,
                        );
                        name = "Build Some";
                        productName = "Build Some";
                        name = SystemLibrariesStatic;
                        productName = SystemLibrariesStatic;
                };
-               3F2EAA9F1A5B85FF007F5A52 /* Build Deprecated */ = {
-                       isa = PBXAggregateTarget;
-                       buildConfigurationList = 3F2EAAA11A5B85FF007F5A52 /* Build configuration list for PBXAggregateTarget "Build Deprecated" */;
-                       buildPhases = (
-                       );
-                       dependencies = (
-                               3F2EAAA71A5B861D007F5A52 /* PBXTargetDependency */,
-                               3F2EAAA51A5B861C007F5A52 /* PBXTargetDependency */,
-                               3F2EAAA91A5B861E007F5A52 /* PBXTargetDependency */,
-                       );
-                       name = "Build Deprecated";
-                       productName = "Build Deprecated";
-               };
                FFA572650AF190F10055A0F1 /* SystemLibrariesDynamic */ = {
                        isa = PBXAggregateTarget;
                        buildConfigurationList = FFA5726E0AF191200055A0F1 /* Build configuration list for PBXAggregateTarget "SystemLibrariesDynamic" */;
@@ -92,7 +84,6 @@
                        );
                        dependencies = (
                                FFB7657D0AEED97F00583A2C /* PBXTargetDependency */,
-                               3F2EAAA31A5B8608007F5A52 /* PBXTargetDependency */,
                                2141DCFD123FFB7D0086D23E /* PBXTargetDependency */,
                        );
                        name = "Build All";
                848DA5D616547F7200D2E8B4 /* dns_xpc.h in Headers */ = {isa = PBXBuildFile; fileRef = 848DA5D516547F7200D2E8B4 /* dns_xpc.h */; };
                848DA5D716547F7200D2E8B4 /* dns_xpc.h in Headers */ = {isa = PBXBuildFile; fileRef = 848DA5D516547F7200D2E8B4 /* dns_xpc.h */; };
                84C5B33C166553F100C324A8 /* dns_services.c in Sources */ = {isa = PBXBuildFile; fileRef = 84C5B339166553AF00C324A8 /* dns_services.c */; };
-               84F4C090188F050200D1E1DE /* dns_services_mdns.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F4C08F188F04CF00D1E1DE /* dns_services_mdns.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               84F4C090188F050200D1E1DE /* dns_services.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F4C08F188F04CF00D1E1DE /* dns_services.h */; settings = {ATTRIBUTES = (Private, ); }; };
                D284BE530ADD80740027CCDF /* DNSServiceDiscoveryDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 6575FBFF022EAFBA00000109 /* DNSServiceDiscoveryDefines.h */; };
                D284BE540ADD80740027CCDF /* dnssd_ipc.h in Headers */ = {isa = PBXBuildFile; fileRef = F5E11B5B04A28126019798ED /* dnssd_ipc.h */; };
                D284BE560ADD80740027CCDF /* DNSServiceDiscoveryReply.defs in Sources */ = {isa = PBXBuildFile; fileRef = 6575FC00022EAFBA00000109 /* DNSServiceDiscoveryReply.defs */; settings = {ATTRIBUTES = (Client, ); }; };
 /* End PBXBuildRule section */
 
 /* Begin PBXContainerItemProxy section */
+               03067D670C83A3830022BE1F /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = D284BE500ADD80740027CCDF;
+                       remoteInfo = mDNSResponder;
+               };
+               03067D690C83A3890022BE1F /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = D284BE750ADD80800027CCDF;
+                       remoteInfo = "mDNSResponder debug";
+               };
                03067D6B0C83A3920022BE1F /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
                        remoteGlobalIDString = D284BEA50ADD80920027CCDF;
                        remoteInfo = "dns-sd tool";
                };
+               03067D6D0C83A39C0022BE1F /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 2E0405EF0C31955500F13B59;
+                       remoteInfo = mDNSResponderHelper;
+               };
                03067D850C849CC30022BE1F /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
                        remoteGlobalIDString = 213FB21712028A7A002B3A08;
                        remoteInfo = BonjourEvents;
                };
-               3F2EAAA21A5B8608007F5A52 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 3F2EAA9F1A5B85FF007F5A52;
-                       remoteInfo = "Build Deprecated";
-               };
-               3F2EAAA41A5B861C007F5A52 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = D284BE750ADD80800027CCDF;
-                       remoteInfo = "mDNSResponder debug";
-               };
-               3F2EAAA61A5B861D007F5A52 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = D284BE500ADD80740027CCDF;
-                       remoteInfo = mDNSResponder;
-               };
-               3F2EAAA81A5B861E007F5A52 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 2E0405EF0C31955500F13B59;
-                       remoteInfo = mDNSResponderHelper;
-               };
                4AE471690EAFF83800A6C5AD /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
                        remoteGlobalIDString = 84C5B3341665529800C324A8;
                        remoteInfo = dns_services;
                };
+               BD7833EF1ABA5E3500EC51ED /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 72FB545E166D5FB00090B2D9;
+                       remoteInfo = dnsctl;
+               };
                D284BF2B0ADD815A0027CCDF /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
                848DA5C6165477E000D2E8B4 /* xpc_services.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xpc_services.c; path = Private/xpc_services.c; sourceTree = "<group>"; };
                848DA5C9165477EB00D2E8B4 /* xpc_services.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xpc_services.h; path = Private/xpc_services.h; sourceTree = "<group>"; };
                848DA5D516547F7200D2E8B4 /* dns_xpc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dns_xpc.h; path = Private/dns_xpc.h; sourceTree = "<group>"; };
-               84C5B3351665529800C324A8 /* libdns_services_mdns.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libdns_services_mdns.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+               84C5B3351665529800C324A8 /* libdns_services.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libdns_services.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                84C5B339166553AF00C324A8 /* dns_services.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = dns_services.c; path = Private/dns_services.c; sourceTree = "<group>"; };
-               84F4C08F188F04CF00D1E1DE /* dns_services_mdns.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dns_services_mdns.h; path = Private/dns_services_mdns.h; sourceTree = "<group>"; };
+               84F4C08F188F04CF00D1E1DE /* dns_services.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dns_services.h; path = Private/dns_services.h; sourceTree = "<group>"; };
                D284BE730ADD80740027CCDF /* mDNSResponder */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = mDNSResponder; sourceTree = BUILT_PRODUCTS_DIR; };
                D284BE950ADD80800027CCDF /* mDNSResponder.debug */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = mDNSResponder.debug; sourceTree = BUILT_PRODUCTS_DIR; };
                D284BEB00ADD80920027CCDF /* dns-sd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "dns-sd"; sourceTree = BUILT_PRODUCTS_DIR; };
                08FB7795FE84155DC02AAC07 /* mDNS Server Sources */ = {
                        isa = PBXGroup;
                        children = (
-                               84F4C08F188F04CF00D1E1DE /* dns_services_mdns.h */,
+                               84F4C08F188F04CF00D1E1DE /* dns_services.h */,
                                216D9ACD1720C9F5008066E1 /* VPNService.c */,
                                2120ABD416B71614007089B6 /* CUPolicy.c */,
                                72FB545A166D5F960090B2D9 /* dnsctl.c */,
                                2141DD1D123FFCDB0086D23E /* libdns_sd.a */,
                                2141DD24123FFD0F0086D23E /* libdns_sd_debug.a */,
                                2141DD2A123FFD2C0086D23E /* libdns_sd_profile.a */,
-                               84C5B3351665529800C324A8 /* libdns_services_mdns.dylib */,
+                               84C5B3351665529800C324A8 /* libdns_services.dylib */,
                                72FB545F166D5FB00090B2D9 /* dnsctl */,
                        );
                        name = Products;
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               84F4C090188F050200D1E1DE /* dns_services_mdns.h in Headers */,
+                               84F4C090188F050200D1E1DE /* dns_services.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        name = dns_services;
                        productName = dns_services;
-                       productReference = 84C5B3351665529800C324A8 /* libdns_services_mdns.dylib */;
+                       productReference = 84C5B3351665529800C324A8 /* libdns_services.dylib */;
                        productType = "com.apple.product-type.library.dynamic";
                };
                D284BE500ADD80740027CCDF /* mDNSResponder */ = {
                08FB7793FE84155DC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               TargetAttributes = {
-                                       3F2EAA9F1A5B85FF007F5A52 = {
-                                               CreatedOnToolsVersion = 6.3;
-                                       };
-                               };
                        };
                        buildConfigurationList = D284BE2B0ADD78180027CCDF /* Build configuration list for PBXProject "mDNSResponder" */;
                        compatibilityVersion = "Xcode 3.1";
                        targets = (
                                00AD62BB032D7A0C0CCA2C71 /* Build More */,
                                03067D640C83A3700022BE1F /* Build Some */,
-                               3F2EAA9F1A5B85FF007F5A52 /* Build Deprecated */,
                                FFB7657B0AEED96B00583A2C /* Build All */,
                                D284BE500ADD80740027CCDF /* mDNSResponder */,
                                D284BE750ADD80800027CCDF /* mDNSResponder debug */,
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                        shellPath = /bin/bash;
-                       shellScript = "# Install mDNSResponder.bundle containing language localizations\nmkdir -p ${DSTROOT}${SYSTEM_LIBRARY_DIR}/CoreServices\ncp -R ${SRCROOT}/mDNSResponder-bundle ${DSTROOT}${SYSTEM_LIBRARY_DIR}/CoreServices/mDNSResponder.bundle\n\n# Remove unwanted CVS directories\nfind ${DSTROOT}${SYSTEM_LIBRARY_DIR}/CoreServices/mDNSResponder.bundle -depth -name CVS -exec rm -rf {} \\;\n\n# Expand UTF-8 files to UTF-16 (at one time this appeared to be necessary, but it's not, so we don't do it any more)\n#foreach file (`find ${DSTROOT}${SYSTEM_LIBRARY_DIR}/CoreServices/mDNSResponder.bundle -name Localizable.strings`)\n#iconv -f utf-8 -t utf-16 ${file} > ${file}.new\n#mv -f ${file}.new ${file}\n#end\n\n# Remove French localization (not wanted for Apple B&I builds)\nrm -rf ${DSTROOT}${SYSTEM_LIBRARY_DIR}/CoreServices/mDNSResponder.bundle/Resources/French.lproj\n\n# Copy Sandbox profile\nif [ ! -z \"${IPHONEOS_DEPLOYMENT_TARGET}\" ] ; then\n  SANDBOXDST=\"${DSTROOT}/usr/local/share/sandbox/profiles/embedded/builtin\"\nelse\n  SANDBOXDST=\"${DSTROOT}/usr/share/sandbox\"\nfi\n(umask 022; mkdir -p -m 0755 \"$SANDBOXDST\")\ncp \"${SRCROOT}/mDNSResponder.sb\" \"${SANDBOXDST}/mDNSResponder.sb\"\n";
+                       shellScript = "# Install mDNSResponder.bundle containing language localizations\nmkdir -p ${DSTROOT}${SYSTEM_LIBRARY_DIR}/CoreServices\ncp -R ${SRCROOT}/mDNSResponder-bundle ${DSTROOT}${SYSTEM_LIBRARY_DIR}/CoreServices/mDNSResponder.bundle\n\n# Remove unwanted CVS directories\nfind ${DSTROOT}${SYSTEM_LIBRARY_DIR}/CoreServices/mDNSResponder.bundle -depth -name CVS -exec rm -rf {} \\;\n\n# Expand UTF-8 files to UTF-16 (at one time this appeared to be necessary, but it's not, so we don't do it any more)\n#foreach file (`find ${DSTROOT}${SYSTEM_LIBRARY_DIR}/CoreServices/mDNSResponder.bundle -name Localizable.strings`)\n#iconv -f utf-8 -t utf-16 ${file} > ${file}.new\n#mv -f ${file}.new ${file}\n#end\n\n# Remove French localization (not wanted for Apple B&I builds)\nrm -rf ${DSTROOT}${SYSTEM_LIBRARY_DIR}/CoreServices/mDNSResponder.bundle/Resources/French.lproj\n\n# Copy Sandbox profile\nif [ -z \"${IPHONEOS_DEPLOYMENT_TARGET}\" -a -z \"${TVOS_DEPLOYMENT_TARGET}\"  ] ; then\n    SANDBOXDST=\"${DSTROOT}/usr/share/sandbox\"\nelse\n    SANDBOXDST=\"${DSTROOT}/usr/local/share/sandbox/profiles/embedded/builtin\"\nfi\n(umask 022; mkdir -p -m 0755 \"$SANDBOXDST\")\ncp \"${SRCROOT}/mDNSResponder.sb\" \"${SANDBOXDST}/mDNSResponder.sb\"\n";
                };
                D284BE760ADD80800027CCDF /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
                        shellPath = /bin/sh;
                        shellScript = "if [ -e \"${SDKROOT}/usr/local/include/dnsinfo.h\" ]\nthen\nrm -f \"${CONFIGURATION_TEMP_DIR}/dnsinfo.h\"\nrm -f \"${CONFIGURATION_TEMP_DIR}/libdnsinfo.a\"\nelse\necho \"#define MDNS_NO_DNSINFO 1\" > ${CONFIGURATION_TEMP_DIR}/dnsinfo.h\ntouch \"${CONFIGURATION_TEMP_DIR}/empty.c\"\nfor i in ${ARCHS}\ndo\nccflags=\"-arch $i $ccflags\"\ndone\ncc ${ccflags} \"${CONFIGURATION_TEMP_DIR}/empty.c\" -c -o \"${CONFIGURATION_TEMP_DIR}/libdnsinfo.a\"\nrm -f \"${CONFIGURATION_TEMP_DIR}/empty.c\"\nfi\n\nif [ -e \"${SDKROOT}/usr/include/sandbox.h\" ]\nthen\nrm -f \"${CONFIGURATION_TEMP_DIR}/sandbox.h\"\nelse\necho \"#define MDNS_NO_SANDBOX 1\" > \"${CONFIGURATION_TEMP_DIR}/sandbox.h\"\nfi\n\nif [ -e \"${SDKROOT}/usr/local/include/vproc.h\" -o -e \"${SDKROOT}/usr/include/vproc.h\" ]\nthen\nrm -f \"${CONFIGURATION_TEMP_DIR}/vproc.h\"\nelse\ntouch \"${CONFIGURATION_TEMP_DIR}/vproc.h\"\nfi\n\nif [ -e \"${SDKROOT}/System/Library/Frameworks/IOKit.framework/PrivateHeaders/pwr_mgt/IOPMLibPrivate.h\" ]\nthen\nrm -rf \"${CONFIGURATION_TEMP_DIR}/IOKit\"\nelse\nmkdir -p \"${CONFIGURATION_TEMP_DIR}/IOKit/pwr_mgt\"\ntouch \"${CONFIGURATION_TEMP_DIR}/IOKit/pwr_mgt/IOPMLibPrivate.h\"\nfi\n\nif [ -e \"${SDKROOT}/System/Library/PrivateFrameworks/DeviceToDeviceManager.framework/Headers/DeviceToDeviceManager.h\" ]\nthen\nrm -rf \"${CONFIGURATION_TEMP_DIR}/DeviceToDeviceManager\"\nelse\nmkdir -p \"${CONFIGURATION_TEMP_DIR}/DeviceToDeviceManager\"\necho \"#define NO_D2D 1\" > \"${CONFIGURATION_TEMP_DIR}/DeviceToDeviceManager/DeviceToDeviceManager.h\"\nfi\n\nif [ -e \"${SDKROOT}/System/Library/PrivateFrameworks/WebFilterDNS.framework/Headers/WebFilterDNS.h\" ]\nthen\nrm -rf \"${CONFIGURATION_TEMP_DIR}/WebFilterDNS\"\nelse\nmkdir -p \"${CONFIGURATION_TEMP_DIR}/WebFilterDNS\"\necho \"#define NO_WCF 1\" > \"${CONFIGURATION_TEMP_DIR}/WebFilterDNS/WebFilterDNS.h\"\nfi\n\nif [ -e \"${SDKROOT}/usr/local/include/AWACS.h\" ]\nthen\nrm -f \"${CONFIGURATION_TEMP_DIR}/AWACS.h\"\nrm -f \"${CONFIGURATION_TEMP_DIR}/libAWACS.a\"\nelse\necho \"#define NO_AWACS 1\" > \"${CONFIGURATION_TEMP_DIR}/AWACS.h\"\ntouch \"${CONFIGURATION_TEMP_DIR}/AWACSempty.c\"\nfor i in ${ARCHS}\ndo\nccflags=\"-arch $i $ccflags\"\ndone\ncc ${ccflags} \"${CONFIGURATION_TEMP_DIR}/AWACSempty.c\" -c -o \"${CONFIGURATION_TEMP_DIR}/libAWACS.a\"\nrm -f \"${CONFIGURATION_TEMP_DIR}/AWACSempty.c\"\nfi";
                };
+               FF045B6A0C7E4AA600448140 /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 8;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+                       shellPath = /bin/sh;
+                       shellScript = "# Install plists to tell launchd how to start mDNSResponder and mDNSResponderHelper\nmkdir -p ${DSTROOT}${SYSTEM_LIBRARY_DIR}/LaunchDaemons\n\nif [ \"${MACOSX_DEPLOYMENT_TARGET}\" == \"10.4\" ] ; then\ncp ${SRCROOT}/LaunchDaemonInfo-Tiger.plist        ${DSTROOT}${SYSTEM_LIBRARY_DIR}/LaunchDaemons/com.apple.mDNSResponder.plist\ncp ${SRCROOT}/LaunchDaemonInfo-Tiger.helper.plist ${DSTROOT}${SYSTEM_LIBRARY_DIR}/LaunchDaemons/com.apple.mDNSResponderHelper.plist\nelse\ncp ${SRCROOT}/LaunchDaemonInfo.plist              ${DSTROOT}${SYSTEM_LIBRARY_DIR}/LaunchDaemons/com.apple.mDNSResponder.plist\ncp ${SRCROOT}/LaunchDaemonInfo.helper.plist       ${DSTROOT}${SYSTEM_LIBRARY_DIR}/LaunchDaemons/com.apple.mDNSResponderHelper.plist\nfi\n\nif [ ! -z \"${IPHONEOS_DEPLOYMENT_TARGET}\" ] ; then\nplutil -convert binary1 ${DSTROOT}${SYSTEM_LIBRARY_DIR}/LaunchDaemons/com.apple.mDNSResponder.plist\nplutil -convert binary1 ${DSTROOT}${SYSTEM_LIBRARY_DIR}/LaunchDaemons/com.apple.mDNSResponderHelper.plist\nfi\n";
+               };
                FF37FAAD0BC581780044A5CF /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 8;
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
+               03067D680C83A3830022BE1F /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = D284BE500ADD80740027CCDF /* mDNSResponder */;
+                       targetProxy = 03067D670C83A3830022BE1F /* PBXContainerItemProxy */;
+               };
+               03067D6A0C83A3890022BE1F /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = D284BE750ADD80800027CCDF /* mDNSResponder debug */;
+                       targetProxy = 03067D690C83A3890022BE1F /* PBXContainerItemProxy */;
+               };
                03067D6C0C83A3920022BE1F /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = D284BEA50ADD80920027CCDF /* dns-sd tool */;
                        targetProxy = 03067D6B0C83A3920022BE1F /* PBXContainerItemProxy */;
                };
+               03067D6E0C83A39C0022BE1F /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 2E0405EF0C31955500F13B59 /* mDNSResponderHelper */;
+                       targetProxy = 03067D6D0C83A39C0022BE1F /* PBXContainerItemProxy */;
+               };
                03067D860C849CC30022BE1F /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 03067D640C83A3700022BE1F /* Build Some */;
                        target = 213FB21712028A7A002B3A08 /* BonjourEvents */;
                        targetProxy = 217A4C48138EE14C000A5BA8 /* PBXContainerItemProxy */;
                };
-               3F2EAAA31A5B8608007F5A52 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 3F2EAA9F1A5B85FF007F5A52 /* Build Deprecated */;
-                       targetProxy = 3F2EAAA21A5B8608007F5A52 /* PBXContainerItemProxy */;
-               };
-               3F2EAAA51A5B861C007F5A52 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = D284BE750ADD80800027CCDF /* mDNSResponder debug */;
-                       targetProxy = 3F2EAAA41A5B861C007F5A52 /* PBXContainerItemProxy */;
-               };
-               3F2EAAA71A5B861D007F5A52 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = D284BE500ADD80740027CCDF /* mDNSResponder */;
-                       targetProxy = 3F2EAAA61A5B861D007F5A52 /* PBXContainerItemProxy */;
-               };
-               3F2EAAA91A5B861E007F5A52 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 2E0405EF0C31955500F13B59 /* mDNSResponderHelper */;
-                       targetProxy = 3F2EAAA81A5B861E007F5A52 /* PBXContainerItemProxy */;
-               };
                4AE4716A0EAFF83800A6C5AD /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 4AE471670EAFF81900A6C5AD /* dns_sd.jar */;
                        target = 84C5B3341665529800C324A8 /* dns_services */;
                        targetProxy = 84C5B3401665544B00C324A8 /* PBXContainerItemProxy */;
                };
+               BD7833F01ABA5E3500EC51ED /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 72FB545E166D5FB00090B2D9 /* dnsctl */;
+                       targetProxy = BD7833EF1ABA5E3500EC51ED /* PBXContainerItemProxy */;
+               };
                D284BF2C0ADD815A0027CCDF /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = D284BEBF0ADD80A20027CCDF /* dnsextd */;
                        };
                        name = Development;
                };
-               3F2EAAA01A5B85FF007F5A52 /* Development */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               PRODUCT_NAME = "$(TARGET_NAME)";
-                       };
-                       name = Development;
-               };
                4AE471680EAFF81900A6C5AD /* Development */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNINITIALIZED_AUTOS = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               INSTALL_PATH = /usr/bin;
+                               INSTALL_PATH = /usr/local/bin;
                                MACOSX_DEPLOYMENT_TARGET = 10.9;
                                ONLY_ACTIVE_ARCH = NO;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                INSTALL_PATH = /usr/lib;
                                MACOSX_DEPLOYMENT_TARGET = 10.8;
                                ONLY_ACTIVE_ARCH = NO;
-                               PRODUCT_NAME = "$(TARGET_NAME)_mdns";
+                               PRODUCT_NAME = "$(TARGET_NAME)";
                                SDKROOT = macosx;
                        };
                        name = Development;
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Development;
                };
-               3F2EAAA11A5B85FF007F5A52 /* Build configuration list for PBXAggregateTarget "Build Deprecated" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               3F2EAAA01A5B85FF007F5A52 /* Development */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Development;
-               };
                4AE471770EAFF84000A6C5AD /* Build configuration list for PBXLegacyTarget "dns_sd.jar" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
index 6effa129e4238ade3cc3aeed403c1be1208a12c6..39cd66c76d85c51b619cfeb8d3ba223ae65ca7e5 100755 (executable)
@@ -906,6 +906,10 @@ mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct
     // If interface is a direct link, address record will be marked as kDNSRecordTypeKnownUnique
     // and skip the probe phase of the probe/announce packet sequence.
     intf->coreIntf.DirectLink = mDNSfalse;
+#ifdef DIRECTLINK_INTERFACE_NAME
+       if (strcmp(intfName, STRINGIFY(DIRECTLINK_INTERFACE_NAME)) == 0)
+               intf->coreIntf.DirectLink = mDNStrue;
+#endif
 
     // The interface is all ready to go, let's register it with the mDNS core.
     if (err == 0)
index c51156a25e20cb2a3aa7c0e43978462d47e0abf3..3831527313436b08ab7d1c5511a9f6f9af3349be 100644 (file)
@@ -66,7 +66,7 @@
  */
 
 #ifndef _DNS_SD_H
-#define _DNS_SD_H 5670000
+#define _DNS_SD_H 5763004
 
 #ifdef  __cplusplus
 extern "C" {
@@ -1961,6 +1961,7 @@ DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
     const void                         *rdata
 );
 
+
 /*********************************************************************************************
 *
 *  NAT Port Mapping
index ea76395a104a759478848086a68b6f14e88ae4b8..cb143104399b530996d4ad9846bf2cc6f76bfe21 100644 (file)
@@ -807,4 +807,5 @@ DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
     return(kDNSServiceErr_Unsupported);
 }
 
+
 #endif  // !MDNS_BUILDINGSTUBLIBRARY
index 4832c683b9e4c46d9e0d17e7a3de914ab9347f1d..5c1d02c468e9c3b86734abc0d0864b84a60d6aeb 100644 (file)
@@ -2093,6 +2093,7 @@ DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
     return err;
 }
 
+
 static void handle_port_mapping_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
 {
     union { uint32_t l; u_char b[4]; } addr;
index 53677bdfabae4a88db5df9a33ebf1f352ee671d7..310df527efb6be51285b95c281924689af1ee3cc 100644 (file)
@@ -1964,6 +1964,23 @@ mDNSlocal mDNSBool CheckForMixedRegistrations(domainname *regtype, domainname *d
     return mDNStrue;
 }
 
+// Returns true if the interfaceIndex value matches one of the pre-defined
+// special values listed in the switch statement below.
+mDNSlocal mDNSBool PreDefinedInterfaceIndex(mDNSu32 interfaceIndex)
+{
+    switch(interfaceIndex)
+    {
+        case kDNSServiceInterfaceIndexAny:
+        case kDNSServiceInterfaceIndexLocalOnly:
+        case kDNSServiceInterfaceIndexUnicast:
+        case kDNSServiceInterfaceIndexP2P:
+            return mDNStrue;
+            break;
+        default:
+            return mDNSfalse;
+    }
+}
+
 mDNSlocal mStatus handle_regservice_request(request_state *request)
 {
     char name[256]; // Lots of spare space for extra-long names that we'll auto-truncate down to 63 bytes
@@ -1987,8 +2004,23 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
     }
 
     InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
+
+    // The registration is scoped to a specific interface index, but the 
+    // interface is not currently in our list.
     if (interfaceIndex && !InterfaceID)
-    { LogMsg("ERROR: handle_regservice_request - Couldn't find interfaceIndex %d", interfaceIndex); return(mStatus_BadParamErr); }
+    {
+        // If it's one of the specially defined inteface index values, just return an error.
+        if (PreDefinedInterfaceIndex(interfaceIndex))
+        {
+            LogMsg("ERROR: handle_regservice_request: bad interfaceIndex %d", interfaceIndex);
+            return(mStatus_BadParamErr);
+        }
+
+        // Otherwise, use the specified interface index value and the registration will
+        // be applied to that interface when it comes up.
+        InterfaceID = (mDNSInterfaceID)(uintptr_t)interfaceIndex;
+        LogInfo("handle_regservice_request: registration pending for interface index %d", interfaceIndex);
+    }
 
     if (get_string(&request->msgptr, request->msgend, name, sizeof(name)) < 0 ||
         get_string(&request->msgptr, request->msgend, type_as_string, MAX_ESCAPED_DOMAIN_NAME) < 0 ||
@@ -2562,7 +2594,23 @@ mDNSlocal mStatus handle_browse_request(request_state *request)
     DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
     mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
     mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
-    if (interfaceIndex && !InterfaceID) return(mStatus_BadParamErr);
+
+    // The browse is scoped to a specific interface index, but the 
+    // interface is not currently in our list.
+    if (interfaceIndex && !InterfaceID)
+    {
+        // If it's one of the specially defined inteface index values, just return an error.
+        if (PreDefinedInterfaceIndex(interfaceIndex))
+        {
+            LogMsg("ERROR: handle_browse_request: bad interfaceIndex %d", interfaceIndex);
+            return(mStatus_BadParamErr);
+        }
+
+        // Otherwise, use the specified interface index value and the browse will
+        // be applied to that interface when it comes up.
+        InterfaceID = (mDNSInterfaceID)(uintptr_t)interfaceIndex;
+        LogInfo("handle_browse_request: browse pending for interface index %d", interfaceIndex);
+    }
 
     if (get_string(&request->msgptr, request->msgend, regtype, MAX_ESCAPED_DOMAIN_NAME) < 0 ||
         get_string(&request->msgptr, request->msgend, domain, MAX_ESCAPED_DOMAIN_NAME) < 0) return(mStatus_BadParamErr);
@@ -2744,8 +2792,23 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
     }
 
     InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
+
+    // The operation is scoped to a specific interface index, but the 
+    // interface is not currently in our list.
     if (interfaceIndex && !InterfaceID)
-    { LogMsg("ERROR: handle_resolve_request bad interfaceIndex %d", interfaceIndex); return(mStatus_BadParamErr); }
+    {
+        // If it's one of the specially defined inteface index values, just return an error.
+        if (PreDefinedInterfaceIndex(interfaceIndex))
+        {
+            LogMsg("ERROR: handle_resolve_request: bad interfaceIndex %d", interfaceIndex);
+            return(mStatus_BadParamErr);
+        }
+
+        // Otherwise, use the specified interface index value and the operation will
+        // be applied to that interface when it comes up.
+        InterfaceID = (mDNSInterfaceID)(uintptr_t)interfaceIndex;
+        LogInfo("handle_resolve_request: resolve pending for interface index %d", interfaceIndex);
+    }
 
     if (get_string(&request->msgptr, request->msgend, name, 256) < 0 ||
         get_string(&request->msgptr, request->msgend, regtype, MAX_ESCAPED_DOMAIN_NAME) < 0 ||
@@ -2773,6 +2836,8 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
     request->u.resolve.qsrv.ForceMCast       = (flags & kDNSServiceFlagsForceMulticast     ) != 0;
     request->u.resolve.qsrv.ReturnIntermed   = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
     request->u.resolve.qsrv.SuppressUnusable = mDNSfalse;
+    request->u.resolve.qsrv.DenyOnCellInterface = mDNSfalse;
+    request->u.resolve.qsrv.DenyOnExpInterface  = mDNSfalse;
     request->u.resolve.qsrv.SearchListIndex  = 0;
     request->u.resolve.qsrv.AppendSearchDomains = 0;
     request->u.resolve.qsrv.RetryWithSearchDomains = mDNSfalse;
@@ -2799,6 +2864,8 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
     request->u.resolve.qtxt.ForceMCast       = (flags & kDNSServiceFlagsForceMulticast     ) != 0;
     request->u.resolve.qtxt.ReturnIntermed   = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
     request->u.resolve.qtxt.SuppressUnusable = mDNSfalse;
+    request->u.resolve.qtxt.DenyOnCellInterface = mDNSfalse;
+    request->u.resolve.qtxt.DenyOnExpInterface  = mDNSfalse;
     request->u.resolve.qtxt.SearchListIndex  = 0;
     request->u.resolve.qtxt.AppendSearchDomains = 0;
     request->u.resolve.qtxt.RetryWithSearchDomains = mDNSfalse;
@@ -3626,7 +3693,23 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
     DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
     mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
     mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
-    if (interfaceIndex && !InterfaceID) return(mStatus_BadParamErr);
+
+    // The request is scoped to a specific interface index, but the 
+    // interface is not currently in our list.
+    if (interfaceIndex && !InterfaceID)
+    {
+        // If it's one of the specially defined inteface index values, just return an error.
+        if (PreDefinedInterfaceIndex(interfaceIndex))
+        {
+            LogMsg("ERROR: handle_queryrecord_request: bad interfaceIndex %d", interfaceIndex);
+            return(mStatus_BadParamErr);
+        }
+
+        // Otherwise, use the specified interface index value and the request will
+        // be applied to that interface when it comes up.
+        InterfaceID = (mDNSInterfaceID)(uintptr_t)interfaceIndex;
+        LogInfo("handle_queryrecord_request: query pending for interface index %d", interfaceIndex);
+    }
 
     if (get_string(&request->msgptr, request->msgend, name, 256) < 0) return(mStatus_BadParamErr);
     rrtype  = get_uint16(&request->msgptr, request->msgend);
@@ -3655,6 +3738,8 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
     q->TimeoutQuestion  = (flags & kDNSServiceFlagsTimeout            ) != 0;
     q->WakeOnResolve    = 0;
     q->UseBackgroundTrafficClass = (flags & kDNSServiceFlagsBackgroundTrafficClass) != 0;
+    q->DenyOnCellInterface = (flags & kDNSServiceFlagsDenyCellular)  != 0;
+    q->DenyOnExpInterface  = (flags & kDNSServiceFlagsDenyExpensive) != 0;
     if ((flags & kDNSServiceFlagsValidate) != 0)
         q->ValidationRequired = DNSSEC_VALIDATION_SECURE;
     else if ((flags & kDNSServiceFlagsValidateOptional) != 0)
@@ -4295,16 +4380,46 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
     char hostname[256];
     domainname d;
     mStatus err = 0;
-
+    mDNSs32 serviceIndex   = -1;  // default unscoped value for ServiceID is -1
+    
     DNSServiceFlags flags  = get_flags(&request->msgptr, request->msgend);
+    
     mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
 
+    if (flags & kDNSServiceFlagsServiceIndex)
+    {
+        // NOTE: kDNSServiceFlagsServiceIndex flag can only be set for DNSServiceGetAddrInfo()
+        LogInfo("DNSServiceGetAddrInfo: kDNSServiceFlagsServiceIndex is SET by the client");
+        // if kDNSServiceFlagsServiceIndex is SET,
+        // interpret the interfaceID as the serviceId and set the interfaceID to 0.
+        serviceIndex   = interfaceIndex;
+        interfaceIndex = 0;
+    }
+    
     mDNSPlatformMemZero(&request->u.addrinfo, sizeof(request->u.addrinfo));
-    request->u.addrinfo.interface_id = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
+
+    mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
+
+    // The request is scoped to a specific interface index, but the 
+    // interface is not currently in our list.
+    if (interfaceIndex && !InterfaceID)
+    {
+        // If it's one of the specially defined inteface index values, just return an error.
+        if (PreDefinedInterfaceIndex(interfaceIndex))
+        {
+            LogMsg("ERROR: handle_addrinfo_request: bad interfaceIndex %d", interfaceIndex);
+            return(mStatus_BadParamErr);
+        }
+
+        // Otherwise, use the specified interface index value and the registration will
+        // be applied to that interface when it comes up.
+        InterfaceID = (mDNSInterfaceID)(uintptr_t)interfaceIndex;
+        LogInfo("handle_addrinfo_request: query pending for interface index %d", interfaceIndex);
+    }
+    request->u.addrinfo.interface_id = InterfaceID;
     request->u.addrinfo.flags        = flags;
     request->u.addrinfo.protocol     = get_uint32(&request->msgptr, request->msgend);
 
-    if (interfaceIndex && !request->u.addrinfo.interface_id) return(mStatus_BadParamErr);
     if (request->u.addrinfo.protocol > (kDNSServiceProtocol_IPv4|kDNSServiceProtocol_IPv6)) return(mStatus_BadParamErr);
 
     if (get_string(&request->msgptr, request->msgend, hostname, 256) < 0) return(mStatus_BadParamErr);
@@ -4325,6 +4440,7 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
     }
 
     request->u.addrinfo.q4.InterfaceID      = request->u.addrinfo.q6.InterfaceID      = request->u.addrinfo.interface_id;
+    request->u.addrinfo.q4.ServiceID        = request->u.addrinfo.q6.ServiceID        = serviceIndex;
     request->u.addrinfo.q4.flags            = request->u.addrinfo.q6.flags            = flags;
     request->u.addrinfo.q4.Target           = request->u.addrinfo.q6.Target           = zeroAddr;
     request->u.addrinfo.q4.qname            = request->u.addrinfo.q6.qname            = d;
@@ -4337,6 +4453,8 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
     request->u.addrinfo.q4.TimeoutQuestion  = request->u.addrinfo.q6.TimeoutQuestion  = (flags & kDNSServiceFlagsTimeout            ) != 0;
     request->u.addrinfo.q4.WakeOnResolve    = request->u.addrinfo.q6.WakeOnResolve    = 0;
     request->u.addrinfo.q4.UseBackgroundTrafficClass = request->u.addrinfo.q6.UseBackgroundTrafficClass  = (flags & kDNSServiceFlagsBackgroundTrafficClass) != 0;
+    request->u.addrinfo.q4.DenyOnCellInterface = request->u.addrinfo.q6.DenyOnCellInterface = (flags & kDNSServiceFlagsDenyCellular) != 0;
+    request->u.addrinfo.q4.DenyOnExpInterface = request->u.addrinfo.q6.DenyOnExpInterface = (flags & kDNSServiceFlagsDenyExpensive) != 0;
     if ((flags & kDNSServiceFlagsValidate) != 0)
         request->u.addrinfo.q4.ValidationRequired = request->u.addrinfo.q6.ValidationRequired = DNSSEC_VALIDATION_SECURE;
     else if ((flags & kDNSServiceFlagsValidateOptional) != 0)