From 49ebc73e1db87793fe536480739cdd31587d554d Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 20 Sep 2018 11:12:30 +0200 Subject: mDNSResponder: Update to v576.30.4 The sources can be obtained via: https://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-576.30.4.tar.gz Update #3522. --- mDNSResponder/Clients/.DS_Store | Bin 6148 -> 0 bytes mDNSResponder/Clients/._.DS_Store | Bin 120 -> 0 bytes mDNSResponder/Clients/dns-sd.c | 3 +- mDNSResponder/Clients/dnsctl.c | 2 +- mDNSResponder/Makefile | 2 +- mDNSResponder/mDNSCore/DNSCommon.c | 2 + mDNSResponder/mDNSCore/mDNS.c | 74 ++++---- mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h | 6 +- mDNSResponder/mDNSCore/uDNS.c | 6 +- mDNSResponder/mDNSMacOSX/CUPolicy.c | 28 ++-- .../mDNSMacOSX/LaunchDaemonInfo.helper.plist | 2 +- mDNSResponder/mDNSMacOSX/LaunchDaemonInfo.plist | 4 +- mDNSResponder/mDNSMacOSX/Private/dns_services.c | 2 +- mDNSResponder/mDNSMacOSX/Private/dns_services.h | 124 ++++++++++++++ .../mDNSMacOSX/Private/dns_services_mdns.h | 124 -------------- mDNSResponder/mDNSMacOSX/VPNService.c | 6 +- mDNSResponder/mDNSMacOSX/daemon.c | 7 +- mDNSResponder/mDNSMacOSX/mDNSMacOSX.c | 186 ++++++++++++++++----- .../mDNSMacOSX/mDNSResponder-entitlements.plist | 8 + mDNSResponder/mDNSMacOSX/mDNSResponder.sb | 6 +- .../mDNSResponder.xcodeproj/project.pbxproj | 169 +++++++++---------- mDNSResponder/mDNSPosix/mDNSPosix.c | 4 + mDNSResponder/mDNSShared/dns_sd.h | 3 +- mDNSResponder/mDNSShared/dnssd_clientshim.c | 1 + mDNSResponder/mDNSShared/dnssd_clientstub.c | 1 + mDNSResponder/mDNSShared/uds_daemon.c | 132 ++++++++++++++- 26 files changed, 570 insertions(+), 332 deletions(-) delete mode 100644 mDNSResponder/Clients/.DS_Store delete mode 100644 mDNSResponder/Clients/._.DS_Store create mode 100644 mDNSResponder/mDNSMacOSX/Private/dns_services.h delete mode 100644 mDNSResponder/mDNSMacOSX/Private/dns_services_mdns.h diff --git a/mDNSResponder/Clients/.DS_Store b/mDNSResponder/Clients/.DS_Store deleted file mode 100644 index c3ebd682..00000000 Binary files a/mDNSResponder/Clients/.DS_Store and /dev/null differ diff --git a/mDNSResponder/Clients/._.DS_Store b/mDNSResponder/Clients/._.DS_Store deleted file mode 100644 index 09fa6bdd..00000000 Binary files a/mDNSResponder/Clients/._.DS_Store and /dev/null differ diff --git a/mDNSResponder/Clients/dns-sd.c b/mDNSResponder/Clients/dns-sd.c index 61c7dcd6..9acf41e5 100644 --- a/mDNSResponder/Clients/dns-sd.c +++ b/mDNSResponder/Clients/dns-sd.c @@ -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; diff --git a/mDNSResponder/Clients/dnsctl.c b/mDNSResponder/Clients/dnsctl.c index b557ac32..bb2a0716 100644 --- a/mDNSResponder/Clients/dnsctl.c +++ b/mDNSResponder/Clients/dnsctl.c @@ -18,7 +18,7 @@ #include // if_nametoindex() #include -#include "dns_services_mdns.h" +#include "dns_services.h" //************************************************************************************************************* // Globals: diff --git a/mDNSResponder/Makefile b/mDNSResponder/Makefile index d7c1919d..647dcf95 100644 --- a/mDNSResponder/Makefile +++ b/mDNSResponder/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 = diff --git a/mDNSResponder/mDNSCore/DNSCommon.c b/mDNSResponder/mDNSCore/DNSCommon.c index 3b2f2ceb..249e3b23 100644 --- a/mDNSResponder/mDNSCore/DNSCommon.c +++ b/mDNSResponder/mDNSCore/DNSCommon.c @@ -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; diff --git a/mDNSResponder/mDNSCore/mDNS.c b/mDNSResponder/mDNSCore/mDNS.c index e15b7cf8..e0af1f1a 100755 --- a/mDNSResponder/mDNSCore/mDNS.c +++ b/mDNSResponder/mDNSCore/mDNS.c @@ -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++; diff --git a/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h b/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h index 81b4192b..bafeb026 100755 --- a/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h +++ b/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h @@ -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); // *************************************************************************** diff --git a/mDNSResponder/mDNSCore/uDNS.c b/mDNSResponder/mDNSCore/uDNS.c index 8c7c3300..ce12d01a 100755 --- a/mDNSResponder/mDNSCore/uDNS.c +++ b/mDNSResponder/mDNSCore/uDNS.c @@ -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); diff --git a/mDNSResponder/mDNSMacOSX/CUPolicy.c b/mDNSResponder/mDNSMacOSX/CUPolicy.c index 434e65cd..187748e1 100644 --- a/mDNSResponder/mDNSMacOSX/CUPolicy.c +++ b/mDNSResponder/mDNSMacOSX/CUPolicy.c @@ -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 diff --git a/mDNSResponder/mDNSMacOSX/LaunchDaemonInfo.helper.plist b/mDNSResponder/mDNSMacOSX/LaunchDaemonInfo.helper.plist index a21868c7..09b61e08 100644 --- a/mDNSResponder/mDNSMacOSX/LaunchDaemonInfo.helper.plist +++ b/mDNSResponder/mDNSMacOSX/LaunchDaemonInfo.helper.plist @@ -3,7 +3,7 @@ Label - com.apple.mDNSResponderHelper + com.apple.mDNSResponderHelper.reloaded OnDemand ProgramArguments diff --git a/mDNSResponder/mDNSMacOSX/LaunchDaemonInfo.plist b/mDNSResponder/mDNSMacOSX/LaunchDaemonInfo.plist index c1fe89a3..4226c795 100644 --- a/mDNSResponder/mDNSMacOSX/LaunchDaemonInfo.plist +++ b/mDNSResponder/mDNSMacOSX/LaunchDaemonInfo.plist @@ -3,9 +3,7 @@ Label - com.apple.networking.mDNSResponder - Disabled - + com.apple.mDNSResponder.reloaded OnDemand InitGroups diff --git a/mDNSResponder/mDNSMacOSX/Private/dns_services.c b/mDNSResponder/mDNSMacOSX/Private/dns_services.c index a14d686c..1df3b21d 100644 --- a/mDNSResponder/mDNSMacOSX/Private/dns_services.c +++ b/mDNSResponder/mDNSMacOSX/Private/dns_services.c @@ -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 #include diff --git a/mDNSResponder/mDNSMacOSX/Private/dns_services.h b/mDNSResponder/mDNSMacOSX/Private/dns_services.h new file mode 100644 index 00000000..7b74e10d --- /dev/null +++ b/mDNSResponder/mDNSMacOSX/Private/dns_services.h @@ -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 + +// 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/mDNSResponder/mDNSMacOSX/Private/dns_services_mdns.h b/mDNSResponder/mDNSMacOSX/Private/dns_services_mdns.h deleted file mode 100644 index 7b74e10d..00000000 --- a/mDNSResponder/mDNSMacOSX/Private/dns_services_mdns.h +++ /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 - -// 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/mDNSResponder/mDNSMacOSX/VPNService.c b/mDNSResponder/mDNSMacOSX/VPNService.c index 8c1bf1d0..623ddbf4 100644 --- a/mDNSResponder/mDNSMacOSX/VPNService.c +++ b/mDNSResponder/mDNSMacOSX/VPNService.c @@ -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; } diff --git a/mDNSResponder/mDNSMacOSX/daemon.c b/mDNSResponder/mDNSMacOSX/daemon.c index acdb68fb..1b257ea2 100644 --- a/mDNSResponder/mDNSMacOSX/daemon.c +++ b/mDNSResponder/mDNSMacOSX/daemon.c @@ -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)", diff --git a/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c b/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c index 28d73f63..f904c8b2 100644 --- a/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c +++ b/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c @@ -115,7 +115,6 @@ D2DStatus D2DTerminate() __attribute__((weak_import)); #include #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); } + + + diff --git a/mDNSResponder/mDNSMacOSX/mDNSResponder-entitlements.plist b/mDNSResponder/mDNSMacOSX/mDNSResponder-entitlements.plist index bb3f05e8..21a343f8 100644 --- a/mDNSResponder/mDNSMacOSX/mDNSResponder-entitlements.plist +++ b/mDNSResponder/mDNSMacOSX/mDNSResponder-entitlements.plist @@ -20,5 +20,13 @@ com.apple.telephony.cupolicy-monitor-access + com.apple.private.necp.match + + com.apple.security.network.server + + com.apple.security.network.client + + com.apple.private.network.awdl.restricted + diff --git a/mDNSResponder/mDNSMacOSX/mDNSResponder.sb b/mDNSResponder/mDNSMacOSX/mDNSResponder.sb index eee623c8..f267f324 100644 --- a/mDNSResponder/mDNSMacOSX/mDNSResponder.sb +++ b/mDNSResponder/mDNSMacOSX/mDNSResponder.sb @@ -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") @@ -135,7 +136,10 @@ (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")) diff --git a/mDNSResponder/mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj b/mDNSResponder/mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj index 7831e19c..39d8a451 100644 --- a/mDNSResponder/mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj +++ b/mDNSResponder/mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj @@ -25,11 +25,16 @@ 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"; @@ -59,19 +64,6 @@ 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"; @@ -210,7 +201,7 @@ 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, ); }; }; @@ -347,6 +338,20 @@ /* 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 */; @@ -354,6 +359,13 @@ 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 */; @@ -410,34 +422,6 @@ 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 */; @@ -452,6 +436,13 @@ 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 */; @@ -679,9 +670,9 @@ 848DA5C6165477E000D2E8B4 /* xpc_services.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xpc_services.c; path = Private/xpc_services.c; sourceTree = ""; }; 848DA5C9165477EB00D2E8B4 /* xpc_services.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xpc_services.h; path = Private/xpc_services.h; sourceTree = ""; }; 848DA5D516547F7200D2E8B4 /* dns_xpc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dns_xpc.h; path = Private/dns_xpc.h; sourceTree = ""; }; - 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 = ""; }; - 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 = ""; }; + 84F4C08F188F04CF00D1E1DE /* dns_services.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dns_services.h; path = Private/dns_services.h; sourceTree = ""; }; 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; }; @@ -930,7 +921,7 @@ 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 */, @@ -1046,7 +1037,7 @@ 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; @@ -1181,7 +1172,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 84F4C090188F050200D1E1DE /* dns_services_mdns.h in Headers */, + 84F4C090188F050200D1E1DE /* dns_services.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1432,7 +1423,7 @@ ); 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 */ = { @@ -1642,11 +1633,6 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - TargetAttributes = { - 3F2EAA9F1A5B85FF007F5A52 = { - CreatedOnToolsVersion = 6.3; - }; - }; }; buildConfigurationList = D284BE2B0ADD78180027CCDF /* Build configuration list for PBXProject "mDNSResponder" */; compatibilityVersion = "Xcode 3.1"; @@ -1664,7 +1650,6 @@ targets = ( 00AD62BB032D7A0C0CCA2C71 /* Build More */, 03067D640C83A3700022BE1F /* Build Some */, - 3F2EAA9F1A5B85FF007F5A52 /* Build Deprecated */, FFB7657B0AEED96B00583A2C /* Build All */, D284BE500ADD80740027CCDF /* mDNSResponder */, D284BE750ADD80800027CCDF /* mDNSResponder debug */, @@ -1841,7 +1826,7 @@ ); 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; @@ -1852,6 +1837,19 @@ 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; @@ -2105,11 +2103,26 @@ /* 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 */; @@ -2150,26 +2163,6 @@ 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 */; @@ -2180,6 +2173,11 @@ target = 84C5B3341665529800C324A8 /* dns_services */; targetProxy = 84C5B3401665544B00C324A8 /* PBXContainerItemProxy */; }; + BD7833F01ABA5E3500EC51ED /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 72FB545E166D5FB00090B2D9 /* dnsctl */; + targetProxy = BD7833EF1ABA5E3500EC51ED /* PBXContainerItemProxy */; + }; D284BF2C0ADD815A0027CCDF /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = D284BEBF0ADD80A20027CCDF /* dnsextd */; @@ -2390,13 +2388,6 @@ }; name = Development; }; - 3F2EAAA01A5B85FF007F5A52 /* Development */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Development; - }; 4AE471680EAFF81900A6C5AD /* Development */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2438,7 +2429,7 @@ 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)"; @@ -2475,7 +2466,7 @@ 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; @@ -2976,14 +2967,6 @@ 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 = ( diff --git a/mDNSResponder/mDNSPosix/mDNSPosix.c b/mDNSResponder/mDNSPosix/mDNSPosix.c index bdfb71f2..1ff9837d 100755 --- a/mDNSResponder/mDNSPosix/mDNSPosix.c +++ b/mDNSResponder/mDNSPosix/mDNSPosix.c @@ -915,6 +915,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) diff --git a/mDNSResponder/mDNSShared/dns_sd.h b/mDNSResponder/mDNSShared/dns_sd.h index c51156a2..38315273 100644 --- a/mDNSResponder/mDNSShared/dns_sd.h +++ b/mDNSResponder/mDNSShared/dns_sd.h @@ -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 diff --git a/mDNSResponder/mDNSShared/dnssd_clientshim.c b/mDNSResponder/mDNSShared/dnssd_clientshim.c index 78322fa5..f6997295 100644 --- a/mDNSResponder/mDNSShared/dnssd_clientshim.c +++ b/mDNSResponder/mDNSShared/dnssd_clientshim.c @@ -817,4 +817,5 @@ DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord return(kDNSServiceErr_Unsupported); } + #endif // !MDNS_BUILDINGSTUBLIBRARY diff --git a/mDNSResponder/mDNSShared/dnssd_clientstub.c b/mDNSResponder/mDNSShared/dnssd_clientstub.c index 4832c683..5c1d02c4 100644 --- a/mDNSResponder/mDNSShared/dnssd_clientstub.c +++ b/mDNSResponder/mDNSShared/dnssd_clientstub.c @@ -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; diff --git a/mDNSResponder/mDNSShared/uds_daemon.c b/mDNSResponder/mDNSShared/uds_daemon.c index 53677bdf..310df527 100644 --- a/mDNSResponder/mDNSShared/uds_daemon.c +++ b/mDNSResponder/mDNSShared/uds_daemon.c @@ -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) -- cgit v1.2.3