mDNSResponder: Update to v625.41.2

The sources can be obtained via:

https://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-625.41.2.tar.gz

Update #3522.
This commit is contained in:
Sebastian Huber 2018-09-19 08:52:21 +02:00
parent 49ebc73e1d
commit f761b290f1
120 changed files with 3706 additions and 7562 deletions

Binary file not shown.

View File

@ -1,8 +1,8 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2008 Apple Inc. All rights reserved.
* Copyright (c) 2008-2011 Apple Inc. All rights reserved.
*
* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
* ("Apple") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this Apple software
* constitutes acceptance of these terms. If you do not agree with these terms,
@ -16,7 +16,7 @@
* the Apple Software in its entirety and without modifications, you must retain
* this notice and the following text and disclaimers in all such redistributions of
* the Apple Software. Neither the name, trademarks, service marks or logos of
* Apple Computer, Inc. may be used to endorse or promote products derived from the
* Apple Inc. may be used to endorse or promote products derived from the
* Apple Software without specific prior written permission from Apple. Except as
* expressly stated in this notice, no other rights or licenses, express or implied,
* are granted by Apple herein, including but not limited to any patent rights that

View File

@ -1,8 +1,8 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2013 Apple Inc. All rights reserved.
* Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
* ("Apple") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this Apple software
* constitutes acceptance of these terms. If you do not agree with these terms,
@ -16,7 +16,7 @@
* the Apple Software in its entirety and without modifications, you must retain
* this notice and the following text and disclaimers in all such redistributions of
* the Apple Software. Neither the name, trademarks, service marks or logos of
* Apple Computer, Inc. may be used to endorse or promote products derived from the
* Apple Inc. may be used to endorse or promote products derived from the
* Apple Software without specific prior written permission from Apple. Except as
* expressly stated in this notice, no other rights or licenses, express or implied,
* are granted by Apple herein, including but not limited to any patent rights that
@ -57,14 +57,6 @@
// aren't in the system's /usr/lib/libSystem.dylib.
//#define TEST_NEW_CLIENTSTUB 1
// When building mDNSResponder for Mac OS X 10.4 and earlier, /usr/lib/libSystem.dylib is built using its own private
// copy of dnssd_clientstub.c, which is old and doesn't have all the entry points defined in the latest version, so
// when we're building dns-sd.c on Mac OS X 10.4 or earlier, we automatically set TEST_NEW_CLIENTSTUB so that we'll
// embed a copy of the latest dnssd_clientstub.c instead of trying to link to the incomplete version in libSystem.dylib
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ <= 1040
#define TEST_NEW_CLIENTSTUB 1
#endif
#include <ctype.h>
#include <stdio.h> // For stdout, stderr
#include <stdlib.h> // For exit()
@ -185,14 +177,6 @@ static const char kFilePathSep = '/';
#include <dispatch/private.h>
#endif
// The "+0" is to cope with the case where _DNS_SD_H is defined but empty (e.g. on Mac OS X 10.4 and earlier)
#if _DNS_SD_H+0 >= 116
#define HAS_NAT_PMP_API 1
#define HAS_ADDRINFO_API 1
#else
#define kDNSServiceFlagsReturnIntermediates 0
#endif
//*************************************************************************************************************
// Globals
@ -421,7 +405,6 @@ done:
#endif //_DNS_SD_LIBDISPATCH
}
#if HAS_NAT_PMP_API | HAS_ADDRINFO_API
static DNSServiceProtocol GetProtocol(const char *s)
{
if (!strcasecmp(s, "v4" )) return(kDNSServiceProtocol_IPv4);
@ -434,7 +417,6 @@ static DNSServiceProtocol GetProtocol(const char *s)
else if (!strcasecmp(s, "tcpudp" )) return(kDNSServiceProtocol_UDP | kDNSServiceProtocol_TCP);
else return(atoi(s));
}
#endif
//*************************************************************************************************************
@ -494,18 +476,14 @@ static void print_usage(const char *arg0, int print_all)
fprintf(stderr, "%s -q <name> <rrtype> <rrclass> (Generic query for any record type)\n", arg0);
fprintf(stderr, "%s -D <name> <rrtype> <rrclass>(Validate query for any record type with DNSSEC)\n", arg0);
fprintf(stderr, "%s -Z <Type> <Domain> (Output results in Zone File format)\n", arg0);
#if HAS_ADDRINFO_API
fprintf(stderr, "%s -G v4/v6/v4v6 <name> (Get address information for hostname)\n", arg0);
fprintf(stderr, "%s -g v4/v6/v4v6 <name> (Validate address info for hostname with DNSSEC)\n", arg0);
#endif
fprintf(stderr, "%s -V (Get version of currently running daemon / system service)\n", arg0);
if (print_all) //Print all available options for dns-sd tool
{
fprintf(stderr, "%s -C <FQDN> <rrtype> <rrclass> (Query; reconfirming each result)\n", arg0);
#if HAS_NAT_PMP_API
fprintf(stderr, "%s -X udp/tcp/udptcp <IntPort> <ExtPort> <TTL> (NAT Port Mapping)\n", arg0);
#endif
fprintf(stderr, "%s -A (Test Adding/Updating/Deleting a record)\n", arg0);
fprintf(stderr, "%s -U (Test updating a TXT record)\n", arg0);
fprintf(stderr, "%s -N (Test adding a large NULL record)\n", arg0);
@ -1041,14 +1019,14 @@ static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags,
case kDNSServiceType_CNAME:
case kDNSServiceType_PTR:
case kDNSServiceType_DNAME:
p += snprintd(p, sizeof(rdb), &rd);
snprintd(p, sizeof(rdb), &rd);
break;
case kDNSServiceType_SOA:
p += snprintd(p, rdb + sizeof(rdb) - p, &rd); // mname
p += snprintf(p, rdb + sizeof(rdb) - p, " ");
p += snprintd(p, rdb + sizeof(rdb) - p, &rd); // rname
p += snprintf(p, rdb + sizeof(rdb) - p, " Ser %d Ref %d Ret %d Exp %d Min %d",
snprintf(p, rdb + sizeof(rdb) - p, " Ser %d Ref %d Ret %d Exp %d Min %d",
ntohl(((uint32_t*)rd)[0]), ntohl(((uint32_t*)rd)[1]), ntohl(((uint32_t*)rd)[2]), ntohl(((uint32_t*)rd)[3]), ntohl(((uint32_t*)rd)[4]));
break;
@ -1062,7 +1040,7 @@ static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags,
p += snprintf(p, rdb + sizeof(rdb) - p, "%d %d %d ", // priority, weight, port
ntohs(*(unsigned short*)rd), ntohs(*(unsigned short*)(rd+2)), ntohs(*(unsigned short*)(rd+4)));
rd += 6;
p += snprintd(p, rdb + sizeof(rdb) - p, &rd); // target host
snprintd(p, rdb + sizeof(rdb) - p, &rd); // target host
break;
case kDNSServiceType_DS:
@ -1124,7 +1102,6 @@ static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags,
fflush(stdout);
}
#if HAS_NAT_PMP_API
static void DNSSD_API port_mapping_create_reply(DNSServiceRef sdref, DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode, uint32_t publicAddress, uint32_t protocol, uint16_t privatePort, uint16_t publicPort, uint32_t ttl, void *context)
{
(void)sdref; // Unused
@ -1146,9 +1123,7 @@ static void DNSSD_API port_mapping_create_reply(DNSServiceRef sdref, DNSServiceF
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
}
#endif
#if HAS_ADDRINFO_API
static void DNSSD_API addrinfo_reply(DNSServiceRef sdref, const DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context)
{
char *op = (flags & kDNSServiceFlagsAdd) ? "Add" : "Rmv";
@ -1218,7 +1193,6 @@ static void DNSSD_API addrinfo_reply(DNSServiceRef sdref, const DNSServiceFlags
if (!(flags & kDNSServiceFlagsMoreComing))
fflush(stdout);
}
#endif
//*************************************************************************************************************
// The main test function
@ -1362,6 +1336,7 @@ static DNSServiceErrorType RegisterProxyAddressRecord(DNSServiceRef sdref, const
// Any DNSService* call will initialize WinSock for us, so we make sure
// DNSServiceCreateConnection() is called before getip() is.
struct sockaddr_storage hostaddr;
memset(&hostaddr, 0, sizeof(hostaddr));
getip(ip, &hostaddr);
flags |= kDNSServiceFlagsUnique;
if (hostaddr.ss_family == AF_INET)
@ -1553,12 +1528,8 @@ int main(int argc, char **argv)
if (argc < 2) goto Fail; // Minimum command line is the command name and one argument
operation = getfirstoption(argc, argv, "EFBZLlRPQqCAUNTMISVHhD"
#if HAS_NAT_PMP_API
"X"
#endif
#if HAS_ADDRINFO_API
"Gg"
#endif
, &opi);
if (operation == -1) goto Fail;
@ -1592,6 +1563,7 @@ int main(int argc, char **argv)
if (dom[0] == '.' && dom[1] == 0) dom[0] = 0; // We allow '.' on the command line as a synonym for empty string
printf("Browsing for %s%s%s\n", typ, dom[0] ? "." : "", dom);
err = DNSServiceCreateConnection(&client);
if (err) { fprintf(stderr, "DNSServiceCreateConnection returned %d\n", err); return(err); }
sc1 = client;
err = DNSServiceBrowse(&sc1, kDNSServiceFlagsShareConnection, opinterface, typ, dom, zonedata_browse, NULL);
break;
@ -1694,7 +1666,6 @@ int main(int argc, char **argv)
break;
}
#if HAS_NAT_PMP_API
case 'X': {
if (argc == opi) // If no arguments, just fetch IP address
err = DNSServiceNATPortMappingCreate(&client, 0, 0, 0, 0, 0, 0, port_mapping_create_reply, NULL);
@ -1711,9 +1682,7 @@ int main(int argc, char **argv)
else goto Fail;
break;
}
#endif
#if HAS_ADDRINFO_API
case 'g':
case 'G': {
flags |= kDNSServiceFlagsReturnIntermediates;
@ -1731,7 +1700,6 @@ int main(int argc, char **argv)
err = DNSServiceGetAddrInfo(&client, flags, opinterface, GetProtocol(argv[opi+0]), argv[opi+1], addrinfo_reply, NULL);
break;
}
#endif
case 'S': {
Opaque16 registerPort = { { 0x23, 0x45 } }; // 9029 decimal

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2012 Apple Inc. All rights reserved.
* Copyright (c) 2012-2015 Apple Inc. All rights reserved.
*
* dnsctl.c
* Command-line tool using libdns_services.dylib
@ -46,7 +46,7 @@ static void printtimestamp(void)
if (strncmp(date, new_date, sizeof(new_date)))
{
printf("DATE: ---%s---\n", new_date);
strncpy(date, new_date, sizeof(date));
strlcpy(date, new_date, sizeof(date));
}
printf("%2d:%02d:%02d.%03d ", tm.tm_hour, tm.tm_min, tm.tm_sec, ms);
}
@ -69,14 +69,14 @@ static void dnsproxy_reply(DNSXConnRef connRef, DNSXErrorType errCode)
printtimestamp();
switch (errCode)
{
case kDNSX_NoError : printf(" SUCCESS \n"); break;
case kDNSX_DictError : printf(" DICT ERROR \n"); break;
case kDNSX_NoError : printf(" SUCCESS \n");
break;
case kDNSX_DaemonNotRunning : printf(" NO DAEMON \n");
DNSXRefDeAlloc(ClientRef); break;
case kDNSX_Engaged : printf(" ENGAGED \n");
case kDNSX_BadParam : printf(" BAD PARAMETER \n");
DNSXRefDeAlloc(ClientRef); break;
case kDNSX_UnknownErr :
default : printf("UNKNOWN ERR \n");
default : printf(" UNKNOWN ERR \n");
DNSXRefDeAlloc(ClientRef); break;
}
fflush(NULL);
@ -118,9 +118,10 @@ int main(int argc, char **argv)
if (argc == 2)
{
printtimestamp();
printf("Proceeding to Enable DNSProxy on mDNSResponder with Default Parameters\n");
printf("Enabling DNSProxy on mDNSResponder with Default Parameters\n");
dispatch_queue_t my_Q = dispatch_queue_create("com.apple.dnsctl.callback_queue", NULL);
err = DNSXEnableProxy(&ClientRef, kDNSProxyEnable, Ipintfs, Opintf, my_Q, dnsproxy_reply);
if (err) fprintf(stderr, "DNSXEnableProxy returned %d\n", err);
}
else if (argc > 2)
{
@ -159,9 +160,10 @@ int main(int argc, char **argv)
}
}
printtimestamp();
printf("Proceeding to Enable DNSProxy on mDNSResponder \n");
printf("Enabling DNSProxy on mDNSResponder \n");
dispatch_queue_t my_Q = dispatch_queue_create("com.apple.dnsctl.callback_queue", NULL);
err = DNSXEnableProxy(&ClientRef, kDNSProxyEnable, Ipintfs, Opintf, my_Q, dnsproxy_reply);
if (err) fprintf(stderr, "DNSXEnableProxy returned %d\n", err);
}
}
else

View File

@ -16,7 +16,7 @@
include $(MAKEFILEPATH)/pb_makefiles/platform.make
MVERS = "mDNSResponder-576.30.4"
MVERS = "mDNSResponder-625.41.2"
DDNSWRITECONFIG = "$(DSTROOT)/Library/Application Support/Bonjour/ddnswriteconfig"
VER =

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CRYPTO_ALG_H
#define __CRYPTO_ALG_H

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -513,7 +513,7 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
expTimeBuf, inceptTimeBuf, swap16(rrsig->keyTag), ((domainname *)(&rrsig->signerName))->c);
len = DomainNameLength((domainname *)&rrsig->signerName);
length += baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + len + RRSIG_FIXED_SIZE),
baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + len + RRSIG_FIXED_SIZE),
rr->rdlength - (len + RRSIG_FIXED_SIZE), ENC_BASE64);
}
break;
@ -521,7 +521,7 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
rdataDNSKey *rrkey = (rdataDNSKey *)rd->data;
length += mDNS_snprintf(buffer+length, RemSpc, "\t%d %d %s %u ", swap16(rrkey->flags), rrkey->proto,
DNSSECAlgName(rrkey->alg), (unsigned int)keytag((mDNSu8 *)rrkey, rr->rdlength));
length += baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + DNSKEY_FIXED_SIZE),
baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + DNSKEY_FIXED_SIZE),
rr->rdlength - DNSKEY_FIXED_SIZE, ENC_BASE64);
}
break;
@ -1481,6 +1481,7 @@ mDNSexport void mDNS_SetupQuestion(DNSQuestion *const q, const mDNSInterfaceID I
q->qnameOrig = mDNSNULL;
q->AnonInfo = mDNSNULL;
q->pid = mDNSPlatformGetPID();
q->euid = 0;
q->DisallowPID = mDNSfalse;
q->ServiceID = -1;
q->QuestionCallback = callback;
@ -2357,13 +2358,9 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
case kDNSType_NSEC: {
// For NSEC records, rdlength represents the exact number of bytes
// of in memory storage.
int len = rr->rdlength;
mDNSu8 *nsec = (mDNSu8 *)rdb->data;
domainname *name = (domainname *)nsec;
int dlen;
dlen = DomainNameLength(name);
len -= dlen;
const int dlen = DomainNameLength(name);
nsec += dlen;
// This function is called when we are sending a NSEC record as part of mDNS,
// or to copy the data to any other buffer needed which could be a mDNS or uDNS
@ -2376,7 +2373,6 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
int i, j, wlen;
wlen = *(nsec + 1);
nsec += 2; // Skip the window number and len
len -= 2;
// For our simplified use of NSEC synthetic records:
//
@ -2406,6 +2402,7 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
else
{
int win, wlen;
int len = rr->rdlength - dlen;
// Sanity check whether the bitmap is good
while (len)
@ -2607,7 +2604,7 @@ mDNSexport mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domain
}
// for dynamic updates
mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease)
mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease)
{
AuthRecord rr;
mDNS_SetupResourceRecord(&rr, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
@ -2616,13 +2613,13 @@ mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease)
rr.resrec.rdestimate = sizeof(rdataOPT);
rr.resrec.rdata->u.opt[0].opt = kDNSOpt_Lease;
rr.resrec.rdata->u.opt[0].u.updatelease = lease;
end = PutResourceRecordTTLJumbo(msg, end, &msg->h.numAdditionals, &rr.resrec, 0);
if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTL"); return mDNSNULL; }
return end;
ptr = PutResourceRecordTTLJumbo(msg, ptr, &msg->h.numAdditionals, &rr.resrec, 0);
if (!ptr) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTL"); return mDNSNULL; }
return ptr;
}
// for dynamic updates
mDNSexport mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease, mDNSu8 *limit)
mDNSexport mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease, mDNSu8 *limit)
{
AuthRecord rr;
mDNS_SetupResourceRecord(&rr, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
@ -2631,9 +2628,9 @@ mDNSexport mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *end, mDNSu32
rr.resrec.rdestimate = sizeof(rdataOPT);
rr.resrec.rdata->u.opt[0].opt = kDNSOpt_Lease;
rr.resrec.rdata->u.opt[0].u.updatelease = lease;
end = PutResourceRecordTTLWithLimit(msg, end, &msg->h.numAdditionals, &rr.resrec, 0, limit);
if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
return end;
ptr = PutResourceRecordTTLWithLimit(msg, ptr, &msg->h.numAdditionals, &rr.resrec, 0, limit);
if (!ptr) { LogMsg("ERROR: putUpdateLeaseWithLimit - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
return ptr;
}
mDNSexport mDNSu8 *putDNSSECOption(DNSMessage *msg, mDNSu8 *end, mDNSu8 *limit)
@ -2650,7 +2647,7 @@ mDNSexport mDNSu8 *putDNSSECOption(DNSMessage *msg, mDNSu8 *end, mDNSu8 *limit)
// set the DO bit
ttl |= 0x8000;
end = PutResourceRecordTTLWithLimit(msg, end, &msg->h.numAdditionals, &rr.resrec, ttl, limit);
if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
if (!end) { LogMsg("ERROR: putDNSSECOption - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
return end;
}
@ -3441,12 +3438,7 @@ mDNSexport const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage
mDNSu16 pktrdlength;
if (largecr == &m->rec && m->rec.r.resrec.RecordType)
{
LogMsg("GetLargeResourceRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
#if ForceAlerts
*(long*)0 = 0;
#endif
}
LogFatalError("GetLargeResourceRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
rr->next = mDNSNULL;
rr->resrec.name = &largecr->namestorage;
@ -3713,7 +3705,7 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
}
ptr = DumpRecords(m, msg, ptr, end, msg->h.numAnswers, IsUpdate ? "Prerequisites" : "Answers");
ptr = DumpRecords(m, msg, ptr, end, msg->h.numAuthorities, IsUpdate ? "Updates" : "Authorities");
ptr = DumpRecords(m, msg, ptr, end, msg->h.numAdditionals, "Additionals");
DumpRecords(m, msg, ptr, end, msg->h.numAdditionals, "Additionals");
LogMsg("--------------");
}
@ -3725,11 +3717,8 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
// Stub definition of TCPSocket_struct so we can access flags field. (Rest of TCPSocket_struct is platform-dependent.)
struct TCPSocket_struct { TCPSocketFlags flags; /* ... */ };
struct UDPSocket_struct
{
mDNSIPPort port; // MUST BE FIRST FIELD -- mDNSCoreReceive expects every UDPSocket_struct to begin with mDNSIPPort port
};
// Stub definition of UDPSocket_struct so we can access port field. (Rest of UDPSocket_struct is platform-dependent.)
struct UDPSocket_struct { mDNSIPPort port; /* ... */ };
// Note: When we sign a DNS message using DNSDigest_SignMessage(), the current real-time clock value is used, which
// is why we generally defer signing until we send the message, to ensure the signature is as fresh as possible.
@ -3844,12 +3833,7 @@ mDNSexport void mDNS_Lock_(mDNS *const m, const char * const functionname)
// If that client callback does mDNS API calls, mDNS_reentrancy and mDNS_busy will both be one
// If mDNS_busy != mDNS_reentrancy that's a bad sign
if (m->mDNS_busy != m->mDNS_reentrancy)
{
LogMsg("%s: mDNS_Lock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
#if ForceAlerts
*(long*)0 = 0;
#endif
}
LogFatalError("%s: mDNS_Lock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
// If this is an initial entry into the mDNSCore code, set m->timenow
// else, if this is a re-entrant entry into the mDNSCore code, m->timenow should already be set
@ -3930,82 +3914,89 @@ mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m)
return(e);
}
#define LogTSE TSE++,LogMsg
mDNSexport void ShowTaskSchedulingError(mDNS *const m)
{
int TSE = 0;
AuthRecord *rr;
mDNS_Lock(m);
LogMsg("Task Scheduling Error: Continuously busy for more than a second");
LogMsg("Task Scheduling Error: *** Continuously busy for more than a second");
// Note: To accurately diagnose *why* we're busy, the debugging code here needs to mirror the logic in GetNextScheduledEvent above
if (m->NewQuestions && (!m->NewQuestions->DelayAnswering || m->timenow - m->NewQuestions->DelayAnswering >= 0))
LogMsg("Task Scheduling Error: NewQuestion %##s (%s)",
LogTSE("Task Scheduling Error: NewQuestion %##s (%s)",
m->NewQuestions->qname.c, DNSTypeName(m->NewQuestions->qtype));
if (m->NewLocalOnlyQuestions)
LogMsg("Task Scheduling Error: NewLocalOnlyQuestions %##s (%s)",
LogTSE("Task Scheduling Error: NewLocalOnlyQuestions %##s (%s)",
m->NewLocalOnlyQuestions->qname.c, DNSTypeName(m->NewLocalOnlyQuestions->qtype));
if (m->NewLocalRecords)
{
rr = AnyLocalRecordReady(m);
if (rr) LogMsg("Task Scheduling Error: NewLocalRecords %s", ARDisplayString(m, rr));
if (rr) LogTSE("Task Scheduling Error: NewLocalRecords %s", ARDisplayString(m, rr));
}
if (m->NewLocalOnlyRecords) LogMsg("Task Scheduling Error: NewLocalOnlyRecords");
if (m->NewLocalOnlyRecords) LogTSE("Task Scheduling Error: NewLocalOnlyRecords");
if (m->SPSProxyListChanged) LogMsg("Task Scheduling Error: SPSProxyListChanged");
if (m->LocalRemoveEvents) LogMsg("Task Scheduling Error: LocalRemoveEvents");
if (m->SPSProxyListChanged) LogTSE("Task Scheduling Error: SPSProxyListChanged");
if (m->timenow - m->NextScheduledEvent >= 0)
LogMsg("Task Scheduling Error: m->NextScheduledEvent %d", m->timenow - m->NextScheduledEvent);
if (m->LocalRemoveEvents) LogTSE("Task Scheduling Error: LocalRemoveEvents");
#ifndef UNICAST_DISABLED
if (m->timenow - m->NextuDNSEvent >= 0)
LogMsg("Task Scheduling Error: m->NextuDNSEvent %d", m->timenow - m->NextuDNSEvent);
LogTSE("Task Scheduling Error: m->NextuDNSEvent %d", m->timenow - m->NextuDNSEvent);
if (m->timenow - m->NextScheduledNATOp >= 0)
LogMsg("Task Scheduling Error: m->NextScheduledNATOp %d", m->timenow - m->NextScheduledNATOp);
LogTSE("Task Scheduling Error: m->NextScheduledNATOp %d", m->timenow - m->NextScheduledNATOp);
if (m->NextSRVUpdate && m->timenow - m->NextSRVUpdate >= 0)
LogMsg("Task Scheduling Error: m->NextSRVUpdate %d", m->timenow - m->NextSRVUpdate);
LogTSE("Task Scheduling Error: m->NextSRVUpdate %d", m->timenow - m->NextSRVUpdate);
#endif
if (m->timenow - m->NextCacheCheck >= 0)
LogMsg("Task Scheduling Error: m->NextCacheCheck %d", m->timenow - m->NextCacheCheck);
LogTSE("Task Scheduling Error: m->NextCacheCheck %d", m->timenow - m->NextCacheCheck);
if (m->timenow - m->NextScheduledSPS >= 0)
LogMsg("Task Scheduling Error: m->NextScheduledSPS %d", m->timenow - m->NextScheduledSPS);
LogTSE("Task Scheduling Error: m->NextScheduledSPS %d", m->timenow - m->NextScheduledSPS);
if (m->timenow - m->NextScheduledKA >= 0)
LogMsg("Task Scheduling Error: m->NextScheduledKA %d", m->timenow - m->NextScheduledKA);
LogTSE("Task Scheduling Error: m->NextScheduledKA %d", m->timenow - m->NextScheduledKA);
if (!m->DelaySleep && m->SleepLimit && m->timenow - m->NextScheduledSPRetry >= 0)
LogMsg("Task Scheduling Error: m->NextScheduledSPRetry %d", m->timenow - m->NextScheduledSPRetry);
LogTSE("Task Scheduling Error: m->NextScheduledSPRetry %d", m->timenow - m->NextScheduledSPRetry);
if (m->DelaySleep && m->timenow - m->DelaySleep >= 0)
LogMsg("Task Scheduling Error: m->DelaySleep %d", m->timenow - m->DelaySleep);
LogTSE("Task Scheduling Error: m->DelaySleep %d", m->timenow - m->DelaySleep);
if (m->SuppressSending && m->timenow - m->SuppressSending >= 0)
LogMsg("Task Scheduling Error: m->SuppressSending %d", m->timenow - m->SuppressSending);
LogTSE("Task Scheduling Error: m->SuppressSending %d", m->timenow - m->SuppressSending);
if (m->timenow - m->NextScheduledQuery >= 0)
LogMsg("Task Scheduling Error: m->NextScheduledQuery %d", m->timenow - m->NextScheduledQuery);
LogTSE("Task Scheduling Error: m->NextScheduledQuery %d", m->timenow - m->NextScheduledQuery);
if (m->timenow - m->NextScheduledProbe >= 0)
LogMsg("Task Scheduling Error: m->NextScheduledProbe %d", m->timenow - m->NextScheduledProbe);
LogTSE("Task Scheduling Error: m->NextScheduledProbe %d", m->timenow - m->NextScheduledProbe);
if (m->timenow - m->NextScheduledResponse >= 0)
LogMsg("Task Scheduling Error: m->NextScheduledResponse %d", m->timenow - m->NextScheduledResponse);
LogTSE("Task Scheduling Error: m->NextScheduledResponse %d", m->timenow - m->NextScheduledResponse);
if (m->timenow - m->NextScheduledStopTime >= 0)
LogTSE("Task Scheduling Error: m->NextScheduledStopTime %d", m->timenow - m->NextScheduledStopTime);
if (m->timenow - m->NextScheduledEvent >= 0)
LogTSE("Task Scheduling Error: m->NextScheduledEvent %d", m->timenow - m->NextScheduledEvent);
if (m->NetworkChanged && m->timenow - m->NetworkChanged >= 0)
LogTSE("Task Scheduling Error: NetworkChanged %d", m->timenow - m->NetworkChanged);
if (!TSE) LogMsg("Task Scheduling Error: *** No likely causes identified");
else LogMsg("Task Scheduling Error: *** %d potential cause%s identified (significant only if the same cause consistently appears)", TSE, TSE > 1 ? "s" : "");
mDNS_Unlock(m);
}
mDNSexport void mDNS_Unlock_(mDNS *const m, const char * const functionname)
mDNSexport void mDNS_Unlock_(mDNS *const m, const char *const functionname)
{
// Decrement mDNS_busy
m->mDNS_busy--;
// Check for locking failures
if (m->mDNS_busy != m->mDNS_reentrancy)
{
LogMsg("%s: mDNS_Unlock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
#if ForceAlerts
*(long*)0 = 0;
#endif
}
LogFatalError("%s: mDNS_Unlock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
// If this is a final exit from the mDNSCore code, set m->NextScheduledEvent and clear m->timenow
if (m->mDNS_busy == 0)

View File

@ -220,7 +220,7 @@ extern mDNSu8 *putDeletionRecord(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *r
extern mDNSu8 *putDeletionRecordWithLimit(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *rr, mDNSu8 *limit);
extern mDNSu8 *putDeleteRRSetWithLimit(DNSMessage *msg, mDNSu8 *ptr, const domainname *name, mDNSu16 rrtype, mDNSu8 *limit);
extern mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domainname *name);
extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease);
extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease);
extern mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease, mDNSu8 *limit);
extern mDNSu8 *putHINFO(const mDNS *const m, DNSMessage *const msg, mDNSu8 *ptr, DomainAuthInfo *authInfo, mDNSu8 *limit);
@ -297,12 +297,12 @@ extern void mDNS_Unlock_(mDNS *const m, const char * const functionname);
#define mDNS_Unlock(X) mDNS_Unlock_((X), __func__)
#define mDNS_CheckLock(X) { if ((X)->mDNS_busy != (X)->mDNS_reentrancy+1) \
LogMsg("%s: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", __func__, (X)->mDNS_busy, (X)->mDNS_reentrancy); }
#define mDNS_CheckLock(X) \
if ((X)->mDNS_busy != (X)->mDNS_reentrancy+1) LogMsg("%s: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", __func__, (X)->mDNS_busy, (X)->mDNS_reentrancy)
#define mDNS_DropLockBeforeCallback() do { m->mDNS_reentrancy++; \
if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Locking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
} while (0)
} while (0)
#define mDNS_ReclaimLockAfterCallback() do { \
if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Unlocking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002-2011 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -15,7 +15,6 @@
* limitations under the License.
*/
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2012-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,6 +27,14 @@
#define ANON_NSEC3_ITERATIONS 1
struct AnonInfoResourceRecord_struct
{
ResourceRecord resrec;
RData rdatastorage;
};
typedef struct AnonInfoResourceRecord_struct AnonInfoResourceRecord;
mDNSlocal mDNSBool InitializeNSEC3Record(ResourceRecord *rr, const mDNSu8 *AnonData, int len, mDNSu32 salt)
{
const mDNSu8 *ptr;
@ -118,9 +126,10 @@ mDNSlocal ResourceRecord *ConstructNSEC3Record(const domainname *service, const
mDNSlocal ResourceRecord *CopyNSEC3ResourceRecord(AnonymousInfo *si, const ResourceRecord *rr)
{
int len;
AnonInfoResourceRecord *anonRR;
domainname *name;
ResourceRecord *nsec3rr;
mDNSu32 neededLen;
mDNSu32 extraLen;
if (rr->rdlength < MCAST_NSEC3_RDLENGTH)
{
@ -128,22 +137,26 @@ mDNSlocal ResourceRecord *CopyNSEC3ResourceRecord(AnonymousInfo *si, const Resou
return mDNSNULL;
}
// Allocate space for the name and the rdata along with the ResourceRecord
len = DomainNameLength(rr->name);
nsec3rr = mDNSPlatformMemAllocate(sizeof(ResourceRecord) + len + sizeof(RData));
if (!nsec3rr)
neededLen = rr->rdlength + DomainNameLength(rr->name);
extraLen = (neededLen > sizeof(RDataBody)) ? (neededLen - sizeof(RDataBody)) : 0;
anonRR = (AnonInfoResourceRecord *)mDNSPlatformMemAllocate(sizeof(AnonInfoResourceRecord) + extraLen);
if (!anonRR)
return mDNSNULL;
*nsec3rr = *rr;
name = (domainname *)((mDNSu8 *)nsec3rr + sizeof(ResourceRecord));
nsec3rr->name = (const domainname *)name;
anonRR->resrec = *rr;
anonRR->rdatastorage.MaxRDLength = rr->rdlength;
mDNSPlatformMemCopy(anonRR->rdatastorage.u.data, rr->rdata->u.data, rr->rdlength);
name = (domainname *)(anonRR->rdatastorage.u.data + rr->rdlength);
AssignDomainName(name, rr->name);
nsec3rr->rdata = (RData *)((mDNSu8 *)nsec3rr->name + len);
mDNSPlatformMemCopy(nsec3rr->rdata->u.data, rr->rdata->u.data, rr->rdlength);
anonRR->resrec.name = name;
anonRR->resrec.rdata = &anonRR->rdatastorage;
si->nsec3RR = nsec3rr;
si->nsec3RR = (ResourceRecord *)anonRR;
return nsec3rr;
return si->nsec3RR;
}
// When a service is started or a browse is started with the Anonymous data, we allocate a new random

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -83,10 +83,6 @@ mDNSlocal void FreeDNSProxyClient(DNSProxyClient *pc)
mDNSlocal mDNSBool ParseEDNS0(DNSProxyClient *pc, const mDNSu8 *ptr, int length, const mDNSu8 *limit)
{
mDNSu16 rrtype, rrclass;
mDNSu8 rcode, version;
mDNSu16 flag;
if (ptr + length > limit)
{
LogInfo("ParseEDNS0: Not enough space in the packet");
@ -94,18 +90,19 @@ mDNSlocal mDNSBool ParseEDNS0(DNSProxyClient *pc, const mDNSu8 *ptr, int length,
}
// Skip the root label
ptr++;
rrtype = (mDNSu16) ((mDNSu16)ptr[0] << 8 | ptr[1]);
mDNSu16 rrtype = (mDNSu16) ((mDNSu16)ptr[0] << 8 | ptr[1]);
if (rrtype != kDNSType_OPT)
{
LogInfo("ParseEDNS0: Not the right type %d", rrtype);
return mDNSfalse;
}
rrclass = (mDNSu16) ((mDNSu16)ptr[2] << 8 | ptr[3]);
rcode = ptr[4];
version = ptr[5];
flag = (mDNSu16) ((mDNSu16)ptr[6] << 8 | ptr[7]);
mDNSu16 rrclass = (mDNSu16) ((mDNSu16)ptr[2] << 8 | ptr[3]);
#if MDNS_DEBUGMSGS
mDNSu8 rcode = ptr[4];
mDNSu8 version = ptr[5];
mDNSu16 flag = (mDNSu16) ((mDNSu16)ptr[6] << 8 | ptr[7]);
debugf("rrtype is %s, length is %d, rcode %d, version %d, flag 0x%x", DNSTypeName(rrtype), rrclass, rcode, version, flag);
#endif
pc->rcvBufSize = rrclass;
pc->DNSSECOK = ptr[6] & 0x80;
@ -366,7 +363,7 @@ again:
return mDNSNULL;
}
len += (ptr - orig);
orig = ptr;
// orig = ptr; Commented out to avoid value never read error message
}
LogInfo("AddResourceRecord: Added %d bytes to the packet", len);
return ptr;
@ -472,13 +469,15 @@ mDNSlocal void ProxyClientCallback(mDNS *const m, DNSQuestion *question, const R
}
}
debugf("ProxyClientCallback: InterfaceID is %p for response to client", pc->interfaceID);
if (!pc->tcp)
{
mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, (UDPSocket *)pc->socket, &pc->addr, pc->port, mDNSNULL, mDNSNULL, mDNSfalse);
mDNSSendDNSMessage(m, &m->omsg, ptr, pc->interfaceID, (UDPSocket *)pc->socket, &pc->addr, pc->port, mDNSNULL, mDNSNULL, mDNSfalse);
}
else
{
mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, mDNSNULL, &pc->addr, pc->port, (TCPSocket *)pc->socket, mDNSNULL, mDNSfalse);
mDNSSendDNSMessage(m, &m->omsg, ptr, pc->interfaceID, mDNSNULL, &pc->addr, pc->port, (TCPSocket *)pc->socket, mDNSNULL, mDNSfalse);
}
done:
@ -502,8 +501,6 @@ mDNSlocal void SendError(mDNS *const m, void *socket, void *const pkt, const mDN
int pktlen = (int)(end - (mDNSu8 *)pkt);
DNSMessage *msg = (DNSMessage *)pkt;
(void) InterfaceID;
// RFC 1035 requires that we copy the question back and RFC 2136 is okay with sending nothing
// in the body or send back whatever we get for updates. It is easy to return whatever we get
// in the question back to the responder. We return as much as we can fit in our standard
@ -517,12 +514,12 @@ mDNSlocal void SendError(mDNS *const m, void *socket, void *const pkt, const mDN
mDNSPlatformMemCopy(m->omsg.data, (mDNSu8 *)&msg->h.numQuestions, pktlen);
if (!tcp)
{
mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, mDNSInterface_Any, socket, dstaddr, dstport, mDNSNULL, mDNSNULL,
mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, InterfaceID, socket, dstaddr, dstport, mDNSNULL, mDNSNULL,
mDNSfalse);
}
else
{
mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, mDNSInterface_Any, mDNSNULL, dstaddr, dstport, (TCPSocket *)socket,
mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, InterfaceID, mDNSNULL, dstaddr, dstport, (TCPSocket *)socket,
mDNSNULL, mDNSfalse);
}
mDNSPlatformDisposeProxyContext(context);
@ -576,7 +573,7 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, void *const pkt,
const mDNSu8 *ptr;
DNSQuestion q, *qptr;
DNSProxyClient *pc;
const mDNSu8 *optRR;
const mDNSu8 *optRR = mDNSNULL;
int optLen = 0;
DNSProxyClient **ppc = &DNSProxyClients;

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __DNS_PROXY_H
#define __DNS_PROXY_H

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mDNSEmbeddedAPI.h"
#include "DNSSECSupport.h"
#include "DNSCommon.h"
@ -309,7 +310,7 @@ mDNSlocal AuthChain *AuthChainCopy(AuthChain *ae)
rvfrom = ae->rrset;
rvto = &ac->rrset;
while (rvfrom)
while (rvfrom && rvto)
{
*rvto = CopyRRVerifier(rvfrom);
rvfrom = rvfrom->next;
@ -318,7 +319,7 @@ mDNSlocal AuthChain *AuthChainCopy(AuthChain *ae)
rvfrom = ae->rrsig;
rvto = &ac->rrsig;
while (rvfrom)
while (rvfrom && rvto)
{
*rvto = CopyRRVerifier(rvfrom);
rvfrom = rvfrom->next;
@ -327,7 +328,7 @@ mDNSlocal AuthChain *AuthChainCopy(AuthChain *ae)
rvfrom = ae->key;
rvto = &ac->key;
while (rvfrom)
while (rvfrom && rvto)
{
*rvto = CopyRRVerifier(rvfrom);
rvfrom = rvfrom->next;
@ -1065,7 +1066,6 @@ mDNSlocal mStatus CheckDSForKey(mDNS *const m, DNSSECVerifier *dv, CacheRecord *
return mStatus_NoError;
else
return mStatus_NoSuchRecord;
return (dv->ds ? mStatus_NoError : mStatus_NoSuchRecord);
}
// It returns mDNStrue if we have all the rrsets for verification and mDNSfalse otherwise.
@ -2335,8 +2335,6 @@ mDNSlocal void SetTTLRRSet(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus statu
rdataRRSig *rrsig;
mDNSu32 slot;
CacheGroup *cg;
int sigNameLen, len;
mDNSu8 *ptr;
mDNSu32 rrTTL, rrsigTTL, rrsigOrigTTL, rrsigTimeTTL;
domainname *qname;
mDNSu16 qtype;
@ -2400,17 +2398,11 @@ mDNSlocal void SetTTLRRSet(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus statu
{
rrsigv = dv->ac->rrsig;
rrsig = (rdataRRSig *)rrsigv->rdata;
sigNameLen = DomainNameLength((domainname *)&rrsig->signerName);
// pointer to signature and the length
ptr = (mDNSu8 *)(rrsigv->rdata + sigNameLen + RRSIG_FIXED_SIZE);
len = rrsigv->rdlength - RRSIG_FIXED_SIZE - sigNameLen;
}
else
{
rrsigv = mDNSNULL;
rrsig = mDNSNULL;
ptr = mDNSNULL;
sigNameLen = len = 0;
}
rrsigRR = mDNSNULL;
@ -3187,14 +3179,11 @@ mDNSexport void VerifySignature(mDNS *const m, DNSSECVerifier *dv, DNSQuestion *
mDNSlocal mDNSBool TrustedKeyPresent(mDNS *const m, DNSSECVerifier *dv)
{
rdataRRSig *rrsig;
rdataDS *ds;
rdataDNSKey *key;
TrustAnchor *ta;
RRVerifier *keyv;
rrsig = (rdataRRSig *)dv->rrsig->rdata;
// Walk all our trusted DS Records to see if we have a matching DNS KEY record that verifies
// the hash. If we find one, verify that this key was used to sign the KEY rrsets in
// this zone. Loop till we find one.

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __DNSSEC_H
#define __DNSSEC_H

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -148,12 +148,18 @@ extern void LogMsgWithLevel(mDNSLogLevel_t logLevel, const char *format, ...) IS
// (or completely overhauled to use the new "log to a separate file" facility)
#define LogMsgNoIdent LogMsg
#if APPLE_OSX_mDNSResponder
extern void LogFatalError(const char *format, ...);
#else
#define LogFatalError LogMsg
#endif
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
extern void *mallocL(char *msg, unsigned int size);
extern void freeL(char *msg, void *x);
extern void LogMemCorruption(const char *format, ...);
extern void uds_validatelists(void);
extern void udns_validatelists(void *const v);
extern void LogMemCorruption(const char *format, ...);
#else
#define mallocL(X,Y) malloc(Y)
#define freeL(X,Y) free(Y)

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -70,6 +70,7 @@
#include "mDNSDebug.h"
#if APPLE_OSX_mDNSResponder
#include <uuid/uuid.h>
#include <TargetConditionals.h>
#endif
#ifdef __cplusplus
@ -90,20 +91,14 @@ extern "C" {
// In order to disable the above features pass the option to your compiler, e.g. -D UNICAST_DISABLED
// Additionally, the LIMITED_RESOURCES_TARGET compile option will eliminate caching and
// and reduce the maximum DNS message sizes.
// Additionally, the LIMITED_RESOURCES_TARGET compile option will reduce the maximum DNS message sizes.
#ifdef LIMITED_RESOURCES_TARGET
// Don't support jumbo frames
#define AbsoluteMaxDNSMessageData 1500
// By the time you add IPv6 header (40 bytes) UDP header (8 bytes) and DNS message header (12 bytes)
// this makes 1560 which is 60 bytes over the standard Ethernet MTU. D'oh!
// 40 (IPv6 header) + 8 (UDP header) + 12 (DNS message header) + 1440 (DNS message body) = 1500 total
#define AbsoluteMaxDNSMessageData 1440
// StandardAuthRDSize is 264 (256+8), which is large enough to hold a maximum-sized SRV record (6 + 256 bytes)
#define MaximumRDSize 264
// Don't cache anything
#define AUTH_HASH_SLOTS 1
#define CACHE_HASH_SLOTS 1
#endif
// ***************************************************************************
@ -556,7 +551,7 @@ typedef packedstruct
{
mDNSu8 vlen;
mDNSu8 tos;
mDNSu16 totlen;
mDNSOpaque16 totlen;
mDNSOpaque16 id;
mDNSOpaque16 flagsfrags;
mDNSu8 ttl;
@ -1320,8 +1315,11 @@ enum
enum
{
DNSServer_FlagDelete = 1,
DNSServer_FlagNew = 2
DNSServer_FlagDelete = 0x1,
DNSServer_FlagNew = 0x2,
#if APPLE_OSX_mDNSResponder
DNSServer_FlagUnreachable = 0x4,
#endif
};
enum
@ -1413,7 +1411,7 @@ struct ResourceRecord_struct
// that are interface-specific (e.g. address records, especially linklocal addresses)
const domainname *name;
RData *rdata; // Pointer to storage for this rdata
DNSServer *rDNSServer; // Unicast DNS server authoritative for this entry;null for multicast
DNSServer *rDNSServer; // Unicast DNS server authoritative for this entry; null for multicast
AnonymousInfo *AnonInfo; // Anonymous Information
};
@ -1502,7 +1500,7 @@ struct AuthRecord_struct
AuthRecord *next; // Next in list; first element of structure for efficiency reasons
// Field Group 1: Common ResourceRecord fields
ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit
ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64)
// Field Group 2: Persistent metadata for Authoritative Records
AuthRecord *Additional1; // Recommended additional record to include in response (e.g. SRV for PTR record)
@ -1634,7 +1632,7 @@ typedef struct ARListElem
struct CacheRecord_struct
{
CacheRecord *next; // Next in list; first element of structure for efficiency reasons
ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit
ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64)
// Transient state for Cache Records
CacheRecord *NextInKAList; // Link to the next element in the chain of known answers to send
@ -1658,13 +1656,12 @@ struct CacheRecord_struct
CacheRecord *soa; // SOA record to return for proxy questions
mDNSAddr sourceAddress; // node from which we received this record
// Size to here is 76 bytes when compiling 32-bit; 104 bytes when compiling 64-bit
// Size to here is 76 bytes when compiling 32-bit; 104 bytes when compiling 64-bit (now 160 bytes for 64-bit)
RData_small smallrdatastorage; // Storage for small records is right here (4 bytes header + 68 bytes data = 72 bytes)
};
// Should match the CacheGroup_struct members, except namestorage[]. Only used to calculate
// the size of the namestorage array in CacheGroup_struct so that
// sizeof(CacheGroup) == sizeof(CacheRecord)
// the size of the namestorage array in CacheGroup_struct so that sizeof(CacheGroup) == sizeof(CacheRecord)
struct CacheGroup_base
{
CacheGroup *next;
@ -1887,6 +1884,17 @@ typedef enum { DNSSECValNotRequired = 0, DNSSECValRequired, DNSSECValInProgress,
// RFC 4122 defines it to be 16 bytes
#define UUID_SIZE 16
#if TARGET_OS_EMBEDDED
typedef struct
{
domainname * originalQName; // Name of original A/AAAA record if this question is for a CNAME record.
mDNSu32 querySendCount; // Number of queries that have been sent to DNS servers so far.
mDNSs32 firstQueryTime; // The time when the first query was sent to a DNS server.
mDNSBool answered; // Has this question been answered?
} uDNSMetrics;
#endif
struct DNSQuestion_struct
{
// Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
@ -1997,9 +2005,13 @@ struct DNSQuestion_struct
mDNSu8 ProxyDNSSECOK; // Proxy Question with EDNS0 DNSSEC OK bit set
mDNSs32 pid; // Process ID of the client that is requesting the question
mDNSu8 uuid[UUID_SIZE]; // Unique ID of the client that is requesting the question (valid only if pid is zero)
mDNSu32 euid; // Effective User Id of the client that is requesting the question
domainname *qnameOrig; // Copy of the original question name if it is not fully qualified
mDNSQuestionCallback *QuestionCallback;
void *QuestionContext;
#if TARGET_OS_EMBEDDED
uDNSMetrics metrics; // Data used for collecting unicast DNS query metrics.
#endif
};
typedef struct
@ -2145,6 +2157,8 @@ struct NetworkInterfaceInfo_struct
mDNSu8 SendGoodbyes; // Send goodbyes on this interface while sleeping
mDNSBool DirectLink; // a direct link, indicating we can skip the probe for
// address records
mDNSBool SupportsUnicastMDNSResponse; // Indicates that the interface supports unicast responses
// to Bonjour queries. Generally true for an interface.
};
#define SLE_DELETE 0x00000001
@ -2259,6 +2273,7 @@ typedef struct
mDNSu32 CacheRefreshed; // Number of times the cache was refreshed due to a response
mDNSu32 WakeOnResolves; // Number of times we did a wake on resolve
} mDNSStatistics;
extern void LogMDNSStatistics(mDNS *const m);
struct mDNS_struct
@ -2269,6 +2284,7 @@ struct mDNS_struct
// all required data is passed as parameters to that function.
mDNS_PlatformSupport *p; // Pointer to platform-specific data of indeterminite size
mDNSs32 NetworkChanged;
mDNSBool CanReceiveUnicastOn5353;
mDNSBool AdvertiseLocalAddresses;
mDNSBool DivertMulticastAdvertisements; // from interfaces that do not advertise local addresses to local-only
@ -2368,7 +2384,7 @@ struct mDNS_struct
mDNSs32 ProbeFailTime;
mDNSu32 NumFailedProbes;
mDNSs32 SuppressProbes;
Platform_t mDNS_plat;
Platform_t mDNS_plat; // Why is this here in the “only required for mDNS Responder” section? -- SC
// Unicast-specific data
mDNSs32 NextuDNSEvent; // uDNS next event
@ -2454,9 +2470,10 @@ struct mDNS_struct
TrustAnchor *TrustAnchors;
int notifyToken;
int uds_listener_skt; // Listening socket for incoming UDS clients
mDNSBool mDNSOppCaching; // Opportunistic Caching
int uds_listener_skt; // Listening socket for incoming UDS clients. This should not be here -- it's private to uds_daemon.c and nothing to do with mDNSCore -- SC
mDNSu32 AutoTargetServices; // # of services that have AutoTarget set
mDNSu32 NumAllInterfaceRecords; // Right now we count *all* multicast records here. Later we may want to change to count interface-specific records separately. (This count includes records on the DuplicateRecords list too.)
mDNSu32 NumAllInterfaceQuestions; // Right now we count *all* multicast questions here. Later we may want to change to count interface-specific questions separately.
DNSSECStatistics DNSSECStats;
mDNSStatistics mDNSStats;
@ -2530,6 +2547,9 @@ extern const mDNSOpaque64 zeroOpaque64;
extern mDNSBool StrictUnicastOrdering;
extern mDNSu8 NumUnicastDNSServers;
#if APPLE_OSX_mDNSResponder
extern mDNSu8 NumUnreachableDNSServers;
#endif
#define localdomain (*(const domainname *)"\x5" "local")
#define DeviceInfoName (*(const domainname *)"\xC" "_device-info" "\x4" "_tcp")
@ -2648,7 +2668,6 @@ extern mStatus mDNS_Init (mDNS *const m, mDNS_PlatformSupport *const p,
extern void mDNS_ConfigChanged(mDNS *const m);
extern void mDNS_GrowCache (mDNS *const m, CacheEntity *storage, mDNSu32 numrecords);
extern void mDNS_GrowAuth (mDNS *const m, AuthEntity *storage, mDNSu32 numrecords);
extern void mDNS_StartExit (mDNS *const m);
extern void mDNS_FinalExit (mDNS *const m);
#define mDNS_Close(m) do { mDNS_StartExit(m); mDNS_FinalExit(m); } while(0)
@ -2784,7 +2803,7 @@ extern mStatus mDNS_AdvertiseDomains(mDNS *const m, AuthRecord *rr, mDNS_DomainT
#define mDNS_StopAdvertiseDomains mDNS_Deregister
extern mDNSOpaque16 mDNS_NewMessageID(mDNS *const m);
extern mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr, mDNSBool *myself);
extern mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr);
extern DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question);
extern mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question);
@ -3195,6 +3214,7 @@ extern mStatus mDNSPlatformGetPrimaryInterface(mDNS *const m, mDNSAddr *v4, m
extern void mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status);
extern void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, const char *reason);
extern void mDNSPlatformPreventSleep(mDNS *const m, mDNSu32 timeout, const char *reason);
extern void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration);
extern mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID);
@ -3317,11 +3337,13 @@ extern void RemoveAutoTunnel6Record(mDNS *const m);
extern mDNSBool RecordReadyForSleep(mDNS *const m, AuthRecord *rr);
// For now this LocalSleepProxy stuff is specific to Mac OS X.
// In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer
extern mStatus ActivateLocalProxy(mDNS *const m, NetworkInterfaceInfo *const intf);
extern mStatus ActivateLocalProxy(mDNS *const m, NetworkInterfaceInfo *const intf, mDNSBool *keepaliveOnly);
extern void mDNSPlatformUpdateDNSStatus(mDNS *const m, DNSQuestion *q);
extern void mDNSPlatformTriggerDNSRetry(mDNS *const m, DNSQuestion *v4q, DNSQuestion *v6q);
extern void mDNSPlatformLogToFile(int log_level, const char *buffer);
extern mDNSBool SupportsInNICProxy(NetworkInterfaceInfo *const intf);
extern mStatus SymptomReporterDNSServerReachable(mDNS *const m, const mDNSAddr *addr);
extern mStatus SymptomReporterDNSServerUnreachable(DNSServer *s);
#endif
typedef void ProxyCallback (mDNS *const m, void *socket, void *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
@ -3336,10 +3358,10 @@ extern mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DNSMes
extern void mDNSPlatformSleepAssertion(mDNS *const m, double timeout);
#endif
extern mDNSBool mDNSPlatformAllowPID(mDNS *const m, DNSQuestion *q);
extern mDNSs32 mDNSPlatformGetServiceID(mDNS *const m, DNSQuestion *q);
extern void mDNSPlatformGetDNSRoutePolicy(mDNS *const m, DNSQuestion *q, mDNSBool *isBlocked);
extern void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q);
extern mDNSs32 mDNSPlatformGetPID(void);
extern mDNSBool mDNSValidKeepAliveRecord(AuthRecord *rr);
// ***************************************************************************
#if 0
@ -3556,21 +3578,18 @@ struct CompileTimeAssertionChecks_mDNS
char sizecheck_AuthRecord [(sizeof(AuthRecord) <= 1208) ? 1 : -1];
char sizecheck_CacheRecord [(sizeof(CacheRecord) <= 232) ? 1 : -1];
char sizecheck_CacheGroup [(sizeof(CacheGroup) <= 232) ? 1 : -1];
char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 832) ? 1 : -1];
char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 864) ? 1 : -1];
// Checks commented out when sizeof(DNSQuestion) change cascaded into having to change yet another
// set of hardcoded size values because these structures contain one or more DNSQuestion
// instances.
// char sizecheck_ZoneData [(sizeof(ZoneData) <= 1648) ? 1 : -1];
char sizecheck_ZoneData [(sizeof(ZoneData) <= 1700) ? 1 : -1];
char sizecheck_NATTraversalInfo [(sizeof(NATTraversalInfo) <= 200) ? 1 : -1];
char sizecheck_HostnameInfo [(sizeof(HostnameInfo) <= 3050) ? 1 : -1];
char sizecheck_DNSServer [(sizeof(DNSServer) <= 340) ? 1 : -1];
// char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 6988) ? 1 : -1];
char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 7184) ? 1 : -1];
char sizecheck_ServiceRecordSet [(sizeof(ServiceRecordSet) <= 5540) ? 1 : -1];
char sizecheck_DomainAuthInfo [(sizeof(DomainAuthInfo) <= 7888) ? 1 : -1];
// char sizecheck_ServiceInfoQuery [(sizeof(ServiceInfoQuery) <= 3302) ? 1 : -1];
char sizecheck_ServiceInfoQuery [(sizeof(ServiceInfoQuery) <= 3488) ? 1 : -1];
#if APPLE_OSX_mDNSResponder
// char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1160) ? 1 : -1];
char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1208) ? 1 : -1];
#endif
};

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -611,7 +611,7 @@ mDNSlocal mDNSBool NSECNoDataError(mDNS *const m, ResourceRecord *rr, domainname
{
const domainname *oname = rr->name; // owner name
if (wildcard) *wildcard = mDNSNULL;
*wildcard = mDNSNULL;
// RFC 4035
//
// section 3.1.3.1 : Name matches. Prove that the type does not exist and also CNAME is
@ -676,10 +676,10 @@ mDNSlocal mDNSBool NSECNoDataError(mDNS *const m, ResourceRecord *rr, domainname
// a subdomain e.g., y.x.example or z.y.x.example and so on.
if (oname->c[0] == 1 && oname->c[1] == '*')
{
int r, s;
int s;
const domainname *ce = SkipLeadingLabels(oname, 1);
r = DNSSECCanonicalOrder(name, ce, &s);
DNSSECCanonicalOrder(name, ce, &s);
if (s)
{
if (RRAssertsExistence(rr, qtype) || RRAssertsExistence(rr, kDNSType_CNAME))
@ -912,18 +912,18 @@ mDNSlocal void NoDataProof(mDNS *const m, DNSSECVerifier *dv, CacheRecord *ncr)
// First verify wildcard NSEC and then when we are done, we
// will verify the noname nsec
dv->pendingNSEC = r;
LogDNSSEC("NoDataProof: Verifying wild and noname %s", RRDisplayString(m, nsec_wild));
LogDNSSEC("NoDataProof: Verifying wild and noname %s", nsec_wild ? RRDisplayString(m, nsec_wild) : "NULL");
VerifyNSEC(m, nsec_wild, mDNSNULL, dv, ncr, NoDataNSECCallback);
}
else if ((dv->flags & WILDCARD_PROVES_NONAME_EXISTS) ||
(dv->flags & NSEC_PROVES_NOTYPE_EXISTS))
{
LogDNSSEC("NoDataProof: Verifying wild %s", RRDisplayString(m, nsec_wild));
LogDNSSEC("NoDataProof: Verifying wild %s", nsec_wild ? RRDisplayString(m, nsec_wild) : "NULL");
VerifyNSEC(m, nsec_wild, mDNSNULL, dv, ncr, mDNSNULL);
}
else if (dv->flags & NSEC_PROVES_NONAME_EXISTS)
{
LogDNSSEC("NoDataProof: Verifying noname %s", RRDisplayString(m, nsec_noname));
LogDNSSEC("NoDataProof: Verifying noname %s", nsec_noname ? RRDisplayString(m, nsec_noname) : "NULL");
VerifyNSEC(m, nsec_noname, mDNSNULL, dv, ncr, mDNSNULL);
}
return;

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __NSEC_H
#define __NSEC_H

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -332,7 +332,7 @@ mDNSlocal mDNSBool NSEC3Find(mDNS *const m, NSEC3FindValues val, CacheRecord *nc
}
}
if ((val == NSEC3Covers || val == NSEC3CEProof) && !(*closerEncloser))
if ((val == NSEC3Covers || val == NSEC3CEProof) && (!closerEncloser || !(*closerEncloser)))
{
if (NSEC3CoversName(m, cr, hashName, hlen, b32Name, b32len))
{
@ -349,14 +349,15 @@ mDNSlocal mDNSBool NSEC3Find(mDNS *const m, NSEC3FindValues val, CacheRecord *nc
// 2.3) If there is a matching NSEC3 RR in the response and the flag
// was set, then the proof is complete, and SNAME is the closest
// encloser.
if (val == NSEC3CEProof)
if (val == NSEC3CEProof && closestEncloser && *closestEncloser)
{
if (*closestEncloser && *closerEncloser)
if (closerEncloser && *closerEncloser)
{
LogDNSSEC("NSEC3Find: Found closest and closer encloser");
return mDNStrue;
}
else
{
// 2.4) If there is a matching NSEC3 RR in the response, but the flag
// is not set, then the response is bogus.
//
@ -364,8 +365,6 @@ mDNSlocal mDNSBool NSEC3Find(mDNS *const m, NSEC3FindValues val, CacheRecord *nc
// happens, we found the closest encloser which means we should have found the closer
// encloser before.
if (*closestEncloser && !(*closerEncloser))
{
LogDNSSEC("NSEC3Find: Found closest, but not closer encloser");
return mDNSfalse;
}
@ -388,8 +387,7 @@ mDNSlocal mDNSBool NSEC3ClosestEncloserProof(mDNS *const m, CacheRecord *ncr, do
// Note: It is possible that closestEncloser and closerEncloser are the same.
if (!closestEncloser || !closerEncloser || !ce)
{
LogMsg("NSEC3ClosestEncloserProof: ClosestEncloser %p or CloserEncloser %p ce %p, something is NULL", *closestEncloser,
*closerEncloser, *ce);
LogMsg("NSEC3ClosestEncloserProof: ClosestEncloser %p or CloserEncloser %p ce %p, something is NULL", closestEncloser, closerEncloser, ce);
return mDNSfalse;
}

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -51,6 +51,9 @@ mDNSBool StrictUnicastOrdering = mDNSfalse;
// arbitrary limitation of 64 DNSServers can be removed.
mDNSu8 NumUnicastDNSServers = 0;
#define MAX_UNICAST_DNS_SERVERS 64
#if APPLE_OSX_mDNSResponder
mDNSu8 NumUnreachableDNSServers = 0;
#endif
#define SetNextuDNSEvent(m, rr) { \
if ((m)->NextuDNSEvent - ((rr)->LastAPTime + (rr)->ThisAPInterval) >= 0) \
@ -164,6 +167,12 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
if (tmp)
{
#if APPLE_OSX_mDNSResponder
if (tmp->flags & DNSServer_FlagDelete)
{
tmp->flags &= ~DNSServer_FlagUnreachable;
}
#endif
tmp->flags &= ~DNSServer_FlagDelete;
*p = tmp; // move to end of list, to ensure ordering from platform layer
}
@ -214,6 +223,7 @@ mDNSexport void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 re
{
DNSServer *new;
DNSServer *orig = q->qDNSServer;
mDNSu8 rcode = '\0';
mDNS_CheckLock(m);
@ -225,9 +235,12 @@ mDNSexport void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 re
if (mDNSOpaque16IsZero(q->responseFlags))
q->responseFlags = responseFlags;
rcode = (mDNSu8)(responseFlags.b[1] & kDNSFlag1_RC_Mask);
// After we reset the qDNSServer to NULL, we could get more SERV_FAILS that might end up
// peanlizing again.
if (!q->qDNSServer) goto end;
if (!q->qDNSServer)
goto end;
// If strict ordering of unicast servers needs to be preserved, we just lookup
// the next best match server below
@ -246,6 +259,10 @@ mDNSexport void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 re
{
LogInfo("PenalizeDNSServer: Not Penalizing PTR question");
}
else if ((rcode == kDNSFlag1_RC_FormErr) || (rcode == kDNSFlag1_RC_ServFail) || (rcode == kDNSFlag1_RC_NotImpl) || (rcode == kDNSFlag1_RC_Refused))
{
LogInfo("PenalizeDNSServer: Not Penalizing DNS Server since it at least responded with rcode %d", rcode);
}
else
{
LogInfo("PenalizeDNSServer: Penalizing question type %d", q->qtype);
@ -812,11 +829,8 @@ mDNSexport mStatus mDNS_StartNATOperation_internal(mDNS *const m, NATTraversalIn
{
if (traversal == *n)
{
LogMsg("Error! Tried to add a NAT traversal that's already in the active list: request %p Prot %d Int %d TTL %d",
LogFatalError("Error! Tried to add a NAT traversal that's already in the active list: request %p Prot %d Int %d TTL %d",
traversal, traversal->Protocol, mDNSVal16(traversal->IntPort), traversal->NATLease);
#if ForceAlerts
*(long*)0 = 0;
#endif
return(mStatus_AlreadyRegistered);
}
if (traversal->Protocol && traversal->Protocol == (*n)->Protocol && mDNSSameIPPort(traversal->IntPort, (*n)->IntPort) &&
@ -1894,6 +1908,7 @@ mDNSlocal mStatus GetZoneData_StartQuery(mDNS *const m, ZoneData *zd, mDNSu16 qt
zd->question.qnameOrig = mDNSNULL;
zd->question.AnonInfo = mDNSNULL;
zd->question.pid = mDNSPlatformGetPID();
zd->question.euid = 0;
zd->question.QuestionCallback = GetZoneData_QuestionCallback;
zd->question.QuestionContext = zd;
@ -2583,6 +2598,7 @@ mDNSlocal void GetStaticHostname(mDNS *m)
q->qnameOrig = mDNSNULL;
q->AnonInfo = mDNSNULL;
q->pid = mDNSPlatformGetPID();
q->euid = 0;
q->QuestionCallback = FoundStaticHostname;
q->QuestionContext = mDNSNULL;
@ -3991,6 +4007,10 @@ mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNS
msg->h.numAnswers, msg->h.numAnswers == 1 ? ", " : "s,",
msg->h.numAuthorities, msg->h.numAuthorities == 1 ? "y, " : "ies,",
msg->h.numAdditionals, msg->h.numAdditionals == 1 ? "" : "s", end - msg->data);
#if APPLE_OSX_mDNSResponder
if (NumUnreachableDNSServers > 0)
SymptomReporterDNSServerReachable(m, srcaddr);
#endif
if (QR_OP == StdR)
{
@ -4141,7 +4161,7 @@ mDNSexport void LLQGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneI
q->servAddr = zeroAddr;
q->servPort = zeroIPPort;
if (!err && zoneInfo && !mDNSIPPortIsZero(zoneInfo->Port) && !mDNSAddressIsZero(&zoneInfo->Addr) && zoneInfo->Host.c[0])
if (!err && !mDNSIPPortIsZero(zoneInfo->Port) && !mDNSAddressIsZero(&zoneInfo->Addr) && zoneInfo->Host.c[0])
{
q->servAddr = zoneInfo->Addr;
q->servPort = zoneInfo->Port;
@ -4238,10 +4258,14 @@ mDNSlocal void PrivateQueryGotZoneData(mDNS *const m, mStatus err, const ZoneDat
// Called in normal callback context (i.e. mDNS_busy and mDNS_reentrancy are both 1)
mDNSexport void RecordRegistrationGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneData)
{
AuthRecord *newRR = (AuthRecord*)zoneData->ZoneDataContext;
AuthRecord *newRR;
AuthRecord *ptr;
int c1, c2;
if (!zoneData) { LogMsg("ERROR: RecordRegistrationGotZoneData invoked with NULL result and no error"); return; }
newRR = (AuthRecord*)zoneData->ZoneDataContext;
if (newRR->nta != zoneData)
LogMsg("RecordRegistrationGotZoneData: nta (%p) != zoneData (%p) %##s (%s)", newRR->nta, zoneData, newRR->resrec.name->c, DNSTypeName(newRR->resrec.rrtype));
@ -4267,8 +4291,6 @@ mDNSexport void RecordRegistrationGotZoneData(mDNS *const m, mStatus err, const
return;
}
if (!zoneData) { LogMsg("ERROR: RecordRegistrationGotZoneData invoked with NULL result and no error"); return; }
if (newRR->resrec.rrclass != zoneData->ZoneClass)
{
LogMsg("ERROR: New resource record's class (%d) does not match zone class (%d)", newRR->resrec.rrclass, zoneData->ZoneClass);
@ -4656,7 +4678,7 @@ mDNSlocal void handle_unanswered_query(mDNS *const m)
// Note: req_DO affects only DNSSEC_VALIDATION_SECURE_OPTIONAL questions;
// DNSSEC_VALIDATION_SECURE questions ignores req_DO.
if (q->qDNSServer && !q->qDNSServer->DNSSECAware && q->qDNSServer->req_DO)
if (!q->qDNSServer->DNSSECAware && q->qDNSServer->req_DO)
{
q->qDNSServer->retransDO++;
if (q->qDNSServer->retransDO == MAX_DNSSEC_RETRANSMISSIONS)
@ -4714,6 +4736,9 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
LogInfo("uDNS_CheckCurrentQuestion: Sent %d unanswered queries for %##s (%s) to %#a:%d (%##s)",
q->unansweredQueries, q->qname.c, DNSTypeName(q->qtype), &orig->addr, mDNSVal16(orig->port), orig->domain.c);
#if APPLE_OSX_mDNSResponder
SymptomReporterDNSServerUnreachable(orig);
#endif
PenalizeDNSServer(m, q, zeroID);
q->noServerResponse = 1;
}
@ -4798,7 +4823,19 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
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);
else
{
err = mDNSSendDNSMessage(m, &m->omsg, end, q->qDNSServer->interface, q->LocalSocket, &q->qDNSServer->addr, q->qDNSServer->port, mDNSNULL, mDNSNULL, q->UseBackgroundTrafficClass);
#if TARGET_OS_EMBEDDED
if (!err)
{
if (q->metrics.querySendCount++ == 0)
{
q->metrics.firstQueryTime = m->timenow;
}
}
#endif
}
}
}
@ -4916,7 +4953,6 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
mDNSexport void CheckNATMappings(mDNS *m)
{
mStatus err = mStatus_NoError;
mDNSBool rfc1918 = mDNSv4AddrIsRFC1918(&m->AdvertisedV4.ip.v4);
mDNSBool HaveRoutable = !rfc1918 && !mDNSIPv4AddressIsZero(m->AdvertisedV4.ip.v4);
m->NextScheduledNATOp = m->timenow + 0x3FFFFFFF;
@ -4974,7 +5010,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
cur->retryInterval = NATMAP_INIT_RETRY;
}
err = uDNS_SendNATMsg(m, cur, mDNStrue); // Will also do UPnP discovery for us, if necessary
uDNS_SendNATMsg(m, cur, mDNStrue); // Will also do UPnP discovery for us, if necessary
if (cur->ExpiryTime) // If have active mapping then set next renewal time halfway to expiry
NATSetNextRenewalTime(m, cur);

View File

@ -1,227 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h> // For printf()
#include <string.h> // For strlen() etc.
#include <Events.h> // For WaitNextEvent()
#include <SIOUX.h> // For SIOUXHandleOneEvent()
#include "mDNSEmbeddedAPI.h" // Defines the interface to the client layer above
#include "mDNSMacOS9.h" // Defines the specific types needed to run mDNS on this platform
// These don't have to be globals, but their memory does need to remain valid for as
// long as the search is going on. They are declared as globals here for simplicity.
static mDNS m;
static mDNS_PlatformSupport p;
static ServiceRecordSet p1, p2, afp, http, njp;
static AuthRecord browsedomain1, browsedomain2;
// This sample code just calls mDNS_RenameAndReregisterService to automatically pick a new
// unique name for the service. For a device such as a printer, this may be appropriate.
// For a device with a user interface, and a screen, and a keyboard, the appropriate
// response may be to prompt the user and ask them to choose a new name for the service.
mDNSlocal void Callback(mDNS *const m, ServiceRecordSet *const sr, mStatus result)
{
switch (result)
{
case mStatus_NoError: debugf("Callback: %##s Name Registered", sr->RR_SRV.resrec.name->c); break;
case mStatus_NameConflict: debugf("Callback: %##s Name Conflict", sr->RR_SRV.resrec.name->c); break;
case mStatus_MemFree: debugf("Callback: %##s Memory Free", sr->RR_SRV.resrec.name->c); break;
default: debugf("Callback: %##s Unknown Result %d", sr->RR_SRV.resrec.name->c, result); break;
}
if (result == mStatus_NameConflict) mDNS_RenameAndReregisterService(m, sr, mDNSNULL);
}
// RegisterService() is a simple wrapper function which takes C string
// parameters, converts them to domainname parameters, and calls mDNS_RegisterService()
mDNSlocal void RegisterService(mDNS *m, ServiceRecordSet *recordset,
UInt16 PortAsNumber, const char txtinfo[],
const domainlabel *const n, const char type[], const char domain[])
{
domainname t;
domainname d;
char buffer[MAX_ESCAPED_DOMAIN_NAME];
UInt8 txtbuffer[512];
MakeDomainNameFromDNSNameString(&t, type);
MakeDomainNameFromDNSNameString(&d, domain);
if (txtinfo)
{
strncpy((char*)txtbuffer+1, txtinfo, sizeof(txtbuffer)-1);
txtbuffer[0] = (UInt8)strlen(txtinfo);
}
else
txtbuffer[0] = 0;
mDNS_RegisterService(m, recordset,
n, &t, &d, // Name, type, domain
mDNSNULL, mDNSOpaque16fromIntVal(PortAsNumber),
txtbuffer, (mDNSu16)(1+txtbuffer[0]), // TXT data, length
mDNSNULL, 0, // Subtypes (none)
mDNSInterface_Any, // Interface ID
Callback, mDNSNULL); // Callback and context
ConvertDomainNameToCString(recordset->RR_SRV.resrec.name, buffer);
printf("Made Service Records for %s\n", buffer);
}
// RegisterFakeServiceForTesting() simulates the effect of services being registered on
// dynamically-allocated port numbers. No real service exists on that port -- this is just for testing.
mDNSlocal void RegisterFakeServiceForTesting(mDNS *m, ServiceRecordSet *recordset, const char txtinfo[],
const char name[], const char type[], const char domain[])
{
static UInt16 NextPort = 0xF000;
domainlabel n;
MakeDomainLabelFromLiteralString(&n, name);
RegisterService(m, recordset, NextPort++, txtinfo, &n, type, domain);
}
// CreateProxyRegistrationForRealService() checks to see if the given port is currently
// in use, and if so, advertises the specified service as present on that port.
// This is useful for advertising existing real services (Personal Web Sharing, Personal
// File Sharing, etc.) that currently don't register with mDNS Service Discovery themselves.
mDNSlocal OSStatus CreateProxyRegistrationForRealService(mDNS *m, UInt16 PortAsNumber, const char txtinfo[],
const char *servicetype, ServiceRecordSet *recordset)
{
InetAddress ia;
TBind bindReq;
OSStatus err;
TEndpointInfo endpointinfo;
EndpointRef ep = OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, &endpointinfo, &err);
if (!ep || err) { printf("OTOpenEndpoint (CreateProxyRegistrationForRealService) failed %d", err); return(err); }
ia.fAddressType = AF_INET;
ia.fPort = mDNSOpaque16fromIntVal(PortAsNumber).NotAnInteger;
ia.fHost = 0;
bindReq.addr.maxlen = sizeof(ia);
bindReq.addr.len = sizeof(ia);
bindReq.addr.buf = (UInt8*)&ia;
bindReq.qlen = 0;
err = OTBind(ep, &bindReq, NULL);
if (err == kOTBadAddressErr)
RegisterService(m, recordset, PortAsNumber, txtinfo, &m->nicelabel, servicetype, "local.");
else if (err)
debugf("OTBind failed %d", err);
OTCloseProvider(ep);
return(noErr);
}
// Done once on startup, and then again every time our address changes
mDNSlocal OSStatus mDNSResponderTestSetup(mDNS *m)
{
char buffer[MAX_ESCAPED_DOMAIN_NAME];
mDNSv4Addr ip = m->HostInterfaces->ip.ip.v4;
ConvertDomainNameToCString(&m->MulticastHostname, buffer);
printf("Name %s\n", buffer);
printf("IP %d.%d.%d.%d\n", ip.b[0], ip.b[1], ip.b[2], ip.b[3]);
printf("\n");
printf("Registering Service Records\n");
// Create example printer discovery records
//static ServiceRecordSet p1, p2;
#define SRSET 0
#if SRSET==0
RegisterFakeServiceForTesting(m, &p1, "path=/index.html", "Web Server One", "_http._tcp.", "local.");
RegisterFakeServiceForTesting(m, &p2, "path=/path.html", "Web Server Two", "_http._tcp.", "local.");
#elif SRSET==1
RegisterFakeServiceForTesting(m, &p1, "rn=lpq1", "Epson Stylus 900N", "_printer._tcp.", "local.");
RegisterFakeServiceForTesting(m, &p2, "rn=lpq2", "HP LaserJet", "_printer._tcp.", "local.");
#else
RegisterFakeServiceForTesting(m, &p1, "rn=lpq3", "My Printer", "_printer._tcp.", "local.");
RegisterFakeServiceForTesting(m, &p2, "lrn=pq4", "My Other Printer", "_printer._tcp.", "local.");
#endif
// If AFP Server is running, register a record for it
CreateProxyRegistrationForRealService(m, 548, "", "_afpovertcp._tcp.", &afp);
// If Web Server is running, register a record for it
CreateProxyRegistrationForRealService(m, 80, "", "_http._tcp.", &http);
// And pretend we always have an NJP server running on port 80 too
//RegisterService(m, &njp, 80, "NJP/", &m->nicelabel, "_njp._tcp.", "local.");
// Advertise that apple.com. is available for browsing
mDNS_AdvertiseDomains(m, &browsedomain1, mDNS_DomainTypeBrowse, mDNSInterface_Any, "apple.com.");
mDNS_AdvertiseDomains(m, &browsedomain2, mDNS_DomainTypeBrowse, mDNSInterface_Any, "IL 2\\4th Floor.apple.com.");
return(kOTNoError);
}
// YieldSomeTime() just cooperatively yields some time to other processes running on classic Mac OS
mDNSlocal Boolean YieldSomeTime(UInt32 milliseconds)
{
extern Boolean SIOUXQuitting;
EventRecord e;
WaitNextEvent(everyEvent, &e, milliseconds / 17, NULL);
SIOUXHandleOneEvent(&e);
return(SIOUXQuitting);
}
int main()
{
mStatus err;
Boolean DoneSetup = false;
SIOUXSettings.asktosaveonclose = false;
SIOUXSettings.userwindowtitle = "\pMulticast DNS Responder";
printf("Multicast DNS Responder\n\n");
printf("This software reports errors using MacsBug breaks,\n");
printf("so if you don't have MacsBug installed your Mac may crash.\n\n");
printf("******************************************************************************\n");
err = InitOpenTransport();
if (err) { debugf("InitOpenTransport failed %d", err); return(err); }
err = mDNS_Init(&m, &p, mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize,
mDNS_Init_AdvertiseLocalAddresses, mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
if (err) return(err);
while (!YieldSomeTime(35))
{
#if MDNS_ONLYSYSTEMTASK
// For debugging, use "#define MDNS_ONLYSYSTEMTASK 1" and call mDNSPlatformIdle() periodically.
// For shipping code, don't define MDNS_ONLYSYSTEMTASK, and you don't need to call mDNSPlatformIdle()
extern void mDNSPlatformIdle(mDNS *const m);
mDNSPlatformIdle(&m); // Only needed for debugging version
#endif
if (m.mDNSPlatformStatus == mStatus_NoError && !DoneSetup)
{
DoneSetup = true;
printf("\nListening for mDNS queries...\n");
mDNSResponderTestSetup(&m);
}
}
if (p1.RR_SRV.resrec.RecordType ) mDNS_DeregisterService(&m, &p1);
if (p2.RR_SRV.resrec.RecordType ) mDNS_DeregisterService(&m, &p2);
if (afp.RR_SRV.resrec.RecordType ) mDNS_DeregisterService(&m, &afp);
if (http.RR_SRV.resrec.RecordType) mDNS_DeregisterService(&m, &http);
if (njp.RR_SRV.resrec.RecordType ) mDNS_DeregisterService(&m, &njp);
mDNS_Close(&m);
return(0);
}

View File

@ -1,243 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h> // For printf()
#include <Events.h> // For WaitNextEvent()
#include <SIOUX.h> // For SIOUXHandleOneEvent()
#include "mDNSEmbeddedAPI.h" // Defines the interface to the client layer above
#include "mDNSMacOS9.h" // Defines the specific types needed to run mDNS on this platform
typedef struct
{
OTLIFO serviceinfolist;
Boolean headerPrinted;
Boolean lostRecords;
} SearcherServices;
typedef struct { ServiceInfo i; mDNSBool add; mDNSBool dom; OTLink link; } linkedServiceInfo;
// These don't have to be globals, but their memory does need to remain valid for as
// long as the search is going on. They are declared as globals here for simplicity.
#define RR_CACHE_SIZE 1000
static CacheEntity rrcachestorage[RR_CACHE_SIZE];
static mDNS mDNSStorage;
static mDNS_PlatformSupport PlatformSupportStorage;
static SearcherServices services;
static DNSQuestion browsequestion, domainquestion;
// PrintServiceInfo prints the service information to standard out
// A real application might want to do something else with the information
static void PrintServiceInfo(SearcherServices *services)
{
OTLink *link = OTReverseList(OTLIFOStealList(&services->serviceinfolist));
while (link)
{
linkedServiceInfo *ls = OTGetLinkObject(link, linkedServiceInfo, link);
ServiceInfo *s = &ls->i;
if (!services->headerPrinted)
{
printf("%-55s Type Domain IP Address Port Info\n", "Name");
services->headerPrinted = true;
}
if (ls->dom)
{
char c_dom[MAX_ESCAPED_DOMAIN_NAME];
ConvertDomainNameToCString(&s->name, c_dom);
if (ls->add) printf("%-55s available for browsing\n", c_dom);
else printf("%-55s no longer available for browsing\n", c_dom);
}
else
{
domainlabel name;
domainname type, domain;
char c_name[MAX_DOMAIN_LABEL+1], c_type[MAX_ESCAPED_DOMAIN_NAME], c_dom[MAX_ESCAPED_DOMAIN_NAME], c_ip[20];
DeconstructServiceName(&s->name, &name, &type, &domain);
ConvertDomainLabelToCString_unescaped(&name, c_name);
ConvertDomainNameToCString(&type, c_type);
ConvertDomainNameToCString(&domain, c_dom);
sprintf(c_ip, "%d.%d.%d.%d", s->ip.ip.v4.b[0], s->ip.ip.v4.b[1], s->ip.ip.v4.b[2], s->ip.ip.v4.b[3]);
printf("%-55s %-16s %-14s ", c_name, c_type, c_dom);
if (ls->add) printf("%-15s %5d %#s\n", c_ip, mDNSVal16(s->port), s->TXTinfo);
else printf("Removed\n");
}
link = link->fNext;
OTFreeMem(ls);
}
}
// When the name, address, port, and txtinfo for a service is found, FoundInstanceInfo()
// enqueues a record for PrintServiceInfo() to print.
// Note, a browsing application would *not* normally need to get all this information --
// all it needs is the name, to display to the user.
// Finding out the address, port, and txtinfo should be deferred to the time that the user
// actually needs to contact the service to use it.
static void FoundInstanceInfo(mDNS *const m, ServiceInfoQuery *query)
{
SearcherServices *services = (SearcherServices *)query->ServiceInfoQueryContext;
linkedServiceInfo *info = (linkedServiceInfo *)(query->info);
if (query->info->ip.type == mDNSAddrType_IPv4)
{
mDNS_StopResolveService(m, query); // For this test code, one answer is sufficient
OTLIFOEnqueue(&services->serviceinfolist, &info->link);
OTFreeMem(query);
}
}
// When a new named instance of a service is found, FoundInstance() is called.
// In this sample code we turn around and immediately issue a query to resolve that service name to
// find its address, port, and txtinfo, but a normal browing application would just display the name.
static void FoundInstance(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
#pragma unused (question)
SearcherServices *services = (SearcherServices *)question->QuestionContext;
linkedServiceInfo *info;
debugf("FoundInstance %##s PTR %##s", answer->name->c, answer->rdata->u.name.c);
if (answer->rrtype != kDNSType_PTR) return;
if (!services) { debugf("FoundInstance: services is NULL"); return; }
info = (linkedServiceInfo *)OTAllocMem(sizeof(linkedServiceInfo));
if (!info) { services->lostRecords = true; return; }
info->i.name = answer->rdata->u.name;
info->i.InterfaceID = answer->InterfaceID;
info->i.ip.type = mDNSAddrType_IPv4;
info->i.ip.ip.v4 = zerov4Addr;
info->i.port = zeroIPPort;
info->add = AddRecord;
info->dom = mDNSfalse;
if (!AddRecord) // If TTL == 0 we're deleting a service,
OTLIFOEnqueue(&services->serviceinfolist, &info->link);
else // else we're adding a new service
{
ServiceInfoQuery *q = (ServiceInfoQuery *)OTAllocMem(sizeof(ServiceInfoQuery));
if (!q) { OTFreeMem(info); services->lostRecords = true; return; }
mDNS_StartResolveService(m, q, &info->i, FoundInstanceInfo, services);
}
}
static void FoundDomain(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
#pragma unused (m)
#pragma unused (question)
SearcherServices *services = (SearcherServices *)question->QuestionContext;
linkedServiceInfo *info;
debugf("FoundDomain %##s PTR %##s", answer->name->c, answer->rdata->u.name.c);
if (answer->rrtype != kDNSType_PTR) return;
if (!services) { debugf("FoundDomain: services is NULL"); return; }
info = (linkedServiceInfo *)OTAllocMem(sizeof(linkedServiceInfo));
if (!info) { services->lostRecords = true; return; }
info->i.name = answer->rdata->u.name;
info->i.InterfaceID = answer->InterfaceID;
info->i.ip.type = mDNSAddrType_IPv4;
info->i.ip.ip.v4 = zerov4Addr;
info->i.port = zeroIPPort;
info->add = AddRecord;
info->dom = mDNStrue;
OTLIFOEnqueue(&services->serviceinfolist, &info->link);
}
// YieldSomeTime() just cooperatively yields some time to other processes running on classic Mac OS
static Boolean YieldSomeTime(UInt32 milliseconds)
{
extern Boolean SIOUXQuitting;
EventRecord e;
WaitNextEvent(everyEvent, &e, milliseconds / 17, NULL);
SIOUXHandleOneEvent(&e);
return(SIOUXQuitting);
}
int main()
{
mStatus err;
Boolean DoneSetup = false;
void *tempmem;
SIOUXSettings.asktosaveonclose = false;
SIOUXSettings.userwindowtitle = "\pMulticast DNS Searcher";
SIOUXSettings.rows = 40;
SIOUXSettings.columns = 132;
printf("Multicast DNS Searcher\n\n");
printf("This software reports errors using MacsBug breaks,\n");
printf("so if you don't have MacsBug installed your Mac may crash.\n\n");
printf("******************************************************************************\n");
err = InitOpenTransport();
if (err) { debugf("InitOpenTransport failed %d", err); return(err); }
err = mDNS_Init(&mDNSStorage, &PlatformSupportStorage, rrcachestorage, RR_CACHE_SIZE,
mDNS_Init_DontAdvertiseLocalAddresses, mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
if (err) return(err);
// Make sure OT has a large enough memory pool for us to draw from at OTNotifier (interrupt) time
tempmem = OTAllocMem(0x10000);
if (tempmem) OTFreeMem(tempmem);
else printf("**** Warning: OTAllocMem couldn't pre-allocate 64K for us.\n");
services.serviceinfolist.fHead = NULL;
services.headerPrinted = false;
services.lostRecords = false;
while (!YieldSomeTime(35))
{
#if MDNS_ONLYSYSTEMTASK
// For debugging, use "#define MDNS_ONLYSYSTEMTASK 1" and call mDNSPlatformIdle() periodically.
// For shipping code, don't define MDNS_ONLYSYSTEMTASK, and you don't need to call mDNSPlatformIdle()
extern void mDNSPlatformIdle(mDNS *const m);
mDNSPlatformIdle(&mDNSStorage); // Only needed for debugging version
#endif
if (mDNSStorage.mDNSPlatformStatus == mStatus_NoError && !DoneSetup)
{
domainname srvtype, srvdom;
DoneSetup = true;
printf("\nSending mDNS service lookup queries and waiting for responses...\n\n");
MakeDomainNameFromDNSNameString(&srvtype, "_http._tcp.");
MakeDomainNameFromDNSNameString(&srvdom, "local.");
err = mDNS_StartBrowse(&mDNSStorage, &browsequestion, &srvtype, &srvdom, mDNSInterface_Any, mDNSfalse, FoundInstance, &services);
if (err) break;
err = mDNS_GetDomains(&mDNSStorage, &domainquestion, mDNS_DomainTypeBrowse, NULL, mDNSInterface_Any, FoundDomain, &services);
if (err) break;
}
if (services.serviceinfolist.fHead)
PrintServiceInfo(&services);
if (services.lostRecords)
{
services.lostRecords = false;
printf("**** Warning: Out of memory: Records have been missed.\n");
}
}
mDNS_StopBrowse(&mDNSStorage, &browsequestion);
mDNS_Close(&mDNSStorage);
return(0);
}

View File

@ -1,48 +0,0 @@
This directory contains support files for running mDNS on Mac OS 9
(and Carbon).
mDNS.mcp is a CodeWarrior 8 project file.
mDNSMacOS9.c and mDNSMacOS9.h are the Platform Support files that go below
mDNS Core.
"Mac OS Test Responder.c" and "Mac OS Test Searcher.c" build an example
standalone (embedded) mDNS Responder and Searcher, respectively.
"mDNSLibrary.c" builds a CFM Shared Library that goes in the Extensions Folder
The CFM Shared Library inplements the same "/usr/include/dns_sd.h" API
that exists on OS X, Windows, Linux, etc., one exception:
- You don't need to call DNSServiceRefSockFD() to get a file descriptor,
and add that file descriptor to your select loop (or equivalent),
wait for data,
and then call DNSServiceProcessResult() every time data arrives.
On OS 9, your callback functions are called "by magic" without having
to do any of this. Of course no magic comes without a price, and
the magic being used here is an OT Notifier function. Your callback
functions are called directly from the OT Notifier function that
received the UDP packet from the wire, which is fast and efficient,
but it does mean that you're being called at OT Notifier time -- so
no QuickDraw calls. If you need to allocate memory in your callback
function, use OTAllocMem(), not NewPtr() or NewHandle(). Typically
what you'll do in your callback function is just update your program's
data structures, and leave screen updating and UI to some foreground
code.
"Searcher.c" and "Responder.c" build sample applications that link with
this CFM Shared Library in the Extensions Folder. You'll see that if
you try to run them without first putting the "Multicast DNS & DNS-SD"
library in the Extensions Folder and restarting, they will report an
error message.
"Searcher.c" builds a sample application that browses for HTTP servers.
"Responder.c" builds a sample application that advertises some test
services. By default it advertises a couple of (nonexistent) HTTP servers
called "Web Server One" and "Web Server Two". In addition, if it finds that
TCP port 548 is occupied, then it concludes that personal file sharing is
running, and advertises the existence of an AFP server. Similarly, if it
finds that TCP port 80 is occupied, then it concludes that personal Web
sharing is running, advertises the existence of an HTTP server.

View File

@ -1,183 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h> // For printf()
#include <string.h> // For strcpy()
#include <Events.h> // For WaitNextEvent()
#include <OpenTransport.h>
#include <OpenTptInternet.h>
#include <SIOUX.h> // For SIOUXHandleOneEvent()
#include "dns_sd.h"
typedef union { UInt8 b[2]; UInt16 NotAnInteger; } mDNSOpaque16;
static UInt16 mDNSVal16(mDNSOpaque16 x) { return((UInt16)(x.b[0]<<8 | x.b[1])); }
static mDNSOpaque16 mDNSOpaque16fromIntVal(UInt16 v)
{ mDNSOpaque16 x; x.b[0] = (UInt8)(v >> 8); x.b[1] = (UInt8)(v & 0xFF); return(x); }
typedef struct RegisteredService_struct RegisteredService;
struct RegisteredService_struct
{
RegisteredService *next;
DNSServiceRef sdRef;
Boolean gotresult;
DNSServiceErrorType errorCode;
char namestr[64];
char typestr[kDNSServiceMaxDomainName];
char domstr [kDNSServiceMaxDomainName];
};
static RegisteredService p1, p2, afp, http, njp;
static RegisteredService *services = NULL, **nextservice = &services;
static void RegCallback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode,
const char *name, const char *regtype, const char *domain, void *context)
{
RegisteredService *rs = (RegisteredService *)context;
(void)sdRef; // Unused
(void)flags; // Unused
rs->gotresult = true;
rs->errorCode = errorCode;
strcpy(rs->namestr, name);
strcpy(rs->typestr, regtype);
strcpy(rs->domstr, domain);
}
static DNSServiceErrorType RegisterService(RegisteredService *rs, mDNSOpaque16 OpaquePort,
const char name[], const char type[], const char domain[], const char txtinfo[])
{
DNSServiceErrorType err;
unsigned char txtbuffer[257];
strncpy((char*)txtbuffer+1, txtinfo, 255);
txtbuffer[256] = 0;
txtbuffer[0] = (unsigned char)strlen((char*)txtbuffer);
rs->gotresult = 0;
rs->errorCode = kDNSServiceErr_NoError;
err = DNSServiceRegister(&rs->sdRef, /* kDNSServiceFlagsAutoRename*/ 0, 0,
name, type, domain, NULL, OpaquePort.NotAnInteger, (unsigned short)(1+txtbuffer[0]), txtbuffer, RegCallback, rs);
if (err)
printf("RegisterService(%s %s %s) failed %d\n", name, type, domain, err);
else
{ *nextservice = rs; nextservice = &rs->next; }
return(err);
}
// RegisterFakeServiceForTesting() simulates the effect of services being registered on
// dynamically-allocated port numbers. No real service exists on that port -- this is just for testing.
static DNSServiceErrorType RegisterFakeServiceForTesting(RegisteredService *rs,
const char name[], const char type[], const char domain[], const char txtinfo[])
{
static UInt16 NextPort = 0xF000;
return RegisterService(rs, mDNSOpaque16fromIntVal(NextPort++), name, type, domain, txtinfo);
}
// CreateProxyRegistrationForRealService() checks to see if the given port is currently
// in use, and if so, advertises the specified service as present on that port.
// This is useful for advertising existing real services (Personal Web Sharing, Personal
// File Sharing, etc.) that currently don't register with mDNS Service Discovery themselves.
static DNSServiceErrorType CreateProxyRegistrationForRealService(RegisteredService *rs,
const char *servicetype, UInt16 PortAsNumber, const char txtinfo[])
{
mDNSOpaque16 OpaquePort = mDNSOpaque16fromIntVal(PortAsNumber);
InetAddress ia;
TBind bindReq;
OSStatus err;
TEndpointInfo endpointinfo;
EndpointRef ep = OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, &endpointinfo, &err);
if (!ep || err) { printf("OTOpenEndpoint (CreateProxyRegistrationForRealService) failed %d", err); return(err); }
ia.fAddressType = AF_INET;
ia.fPort = OpaquePort.NotAnInteger;
ia.fHost = 0;
bindReq.addr.maxlen = sizeof(ia);
bindReq.addr.len = sizeof(ia);
bindReq.addr.buf = (UInt8*)&ia;
bindReq.qlen = 0;
err = OTBind(ep, &bindReq, NULL);
if (err == kOTBadAddressErr)
err = RegisterService(rs, OpaquePort, "", servicetype, "local.", txtinfo);
else if (err)
printf("OTBind failed %d", err);
OTCloseProvider(ep);
return(err);
}
// YieldSomeTime() just cooperatively yields some time to other processes running on classic Mac OS
static Boolean YieldSomeTime(UInt32 milliseconds)
{
extern Boolean SIOUXQuitting;
EventRecord e;
WaitNextEvent(everyEvent, &e, milliseconds / 17, NULL);
SIOUXHandleOneEvent(&e);
return(SIOUXQuitting);
}
int main()
{
OSStatus err;
RegisteredService *s;
SIOUXSettings.asktosaveonclose = false;
SIOUXSettings.userwindowtitle = "\pMulticast DNS Responder";
printf("Multicast DNS Responder\n\n");
printf("This software reports errors using MacsBug breaks,\n");
printf("so if you don't have MacsBug installed your Mac may crash.\n\n");
printf("******************************************************************************\n\n");
err = InitOpenTransport();
if (err) { printf("InitOpenTransport failed %d", err); return(err); }
printf("Advertising Services...\n");
#define SRSET 0
#if SRSET==0
RegisterFakeServiceForTesting(&p1, "Web Server One", "_http._tcp.", "local.", "path=/index.html");
RegisterFakeServiceForTesting(&p2, "Web Server Two", "_http._tcp.", "local.", "path=/path.html");
#elif SRSET==1
RegisterFakeServiceForTesting(&p1, "Epson Stylus 900N", "_printer._tcp.", "local.", "rn=lpq1");
RegisterFakeServiceForTesting(&p2, "HP LaserJet", "_printer._tcp.", "local.", "rn=lpq2");
#else
RegisterFakeServiceForTesting(&p1, "My Printer", "_printer._tcp.", "local.", "rn=lpq3");
RegisterFakeServiceForTesting(&p2, "My Other Printer", "_printer._tcp.", "local.", "lrn=pq4");
#endif
// If AFP Server is running, register a record for it
CreateProxyRegistrationForRealService(&afp, "_afpovertcp._tcp.", 548, "");
// If Web Server is running, register a record for it
CreateProxyRegistrationForRealService(&http, "_http._tcp.", 80, "path=/index.html");
while (!YieldSomeTime(35))
for (s = services; s; s = s->next)
if (s->gotresult)
{
printf("%s %s %s registered\n", s->namestr, s->typestr, s->domstr);
s->gotresult = false;
}
for (s = services; s; s = s->next)
if (s->sdRef) DNSServiceRefDeallocate(s->sdRef);
CloseOpenTransport();
return(0);
}

View File

@ -1,240 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h> // For printf()
#include <string.h> // For strcpy()
#include <Events.h> // For WaitNextEvent()
#include <CodeFragments.h> // For SIOkUnresolvedCFragSymbolAddress
#include <SIOUX.h> // For SIOUXHandleOneEvent()
#include <OpenTransport.h>
#include <OpenTptInternet.h>
#include "dns_sd.h"
#define ns_c_in 1
#define ns_t_a 1
typedef union { UInt8 b[2]; UInt16 NotAnInteger; } mDNSOpaque16;
static UInt16 mDNSVal16(mDNSOpaque16 x) { return((UInt16)(x.b[0]<<8 | x.b[1])); }
static mDNSOpaque16 mDNSOpaque16fromIntVal(UInt16 v)
{ mDNSOpaque16 x; x.b[0] = (UInt8)(v >> 8); x.b[1] = (UInt8)(v & 0xFF); return(x); }
typedef struct
{
OTLIFO serviceinfolist;
Boolean headerPrinted;
Boolean lostRecords;
} SearcherServices;
typedef struct
{
SearcherServices *services;
char name[kDNSServiceMaxDomainName];
char type[kDNSServiceMaxDomainName];
char domn[kDNSServiceMaxDomainName];
char host[kDNSServiceMaxDomainName];
char text[kDNSServiceMaxDomainName];
InetHost address;
mDNSOpaque16 notAnIntPort;
DNSServiceRef sdRef;
Boolean add;
Boolean dom;
OTLink link;
} linkedServiceInfo;
static SearcherServices services;
// PrintServiceInfo prints the service information to standard out
// A real application might want to do something else with the information
static void PrintServiceInfo(SearcherServices *services)
{
OTLink *link = OTReverseList(OTLIFOStealList(&services->serviceinfolist));
while (link)
{
linkedServiceInfo *s = OTGetLinkObject(link, linkedServiceInfo, link);
if (!services->headerPrinted)
{
printf("%-55s Type Domain Target Host IP Address Port Info\n", "Name");
services->headerPrinted = true;
}
if (s->dom)
{
if (s->add) printf("%-55s available for browsing\n", s->domn);
else printf("%-55s no longer available for browsing\n", s->domn);
}
else
{
char ip[16];
unsigned char *p = (unsigned char *)&s->address;
sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
printf("%-55s %-16s %-14s ", s->name, s->type, s->domn);
if (s->add) printf("%-15s %-15s %5d %s\n", s->host, ip, mDNSVal16(s->notAnIntPort), s->text);
else printf("Removed\n");
}
link = link->fNext;
OTFreeMem(s);
}
}
static void FoundInstanceAddress(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode,
const char *fullname, uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata, uint32_t ttl, void *context)
{
linkedServiceInfo *info = (linkedServiceInfo *)context;
SearcherServices *services = info->services;
(void)sdRef; // Unused
(void)interfaceIndex; // Unused
(void)fullname; // Unused
(void)ttl; // Unused
if (errorCode == kDNSServiceErr_NoError)
if (flags & kDNSServiceFlagsAdd)
if (rrclass == ns_c_in && rrtype == ns_t_a && rdlen == sizeof(info->address))
{
memcpy(&info->address, rdata, sizeof(info->address));
DNSServiceRefDeallocate(info->sdRef);
OTLIFOEnqueue(&services->serviceinfolist, &info->link);
}
}
static void FoundInstanceInfo(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t notAnIntPort,
uint16_t txtLen, const unsigned char *txtRecord, void *context)
{
linkedServiceInfo *info = (linkedServiceInfo *)context;
SearcherServices *services = info->services;
(void)sdRef; // Unused
(void)flags; // Unused
(void)interfaceIndex; // Unused
(void)errorCode; // Unused
(void)fullname; // Unused
strcpy(info->host, hosttarget);
if (txtLen == 0) info->text[0] = 0;
else
{
strncpy(info->text, (char *)txtRecord+1, txtRecord[0]);
info->text[txtRecord[0]] = 0;
}
info->notAnIntPort.NotAnInteger = notAnIntPort;
DNSServiceRefDeallocate(info->sdRef);
DNSServiceQueryRecord(&info->sdRef, 0, 0, info->host, ns_t_a, ns_c_in, FoundInstanceAddress, info);
}
// When a new named instance of a service is found, FoundInstance() is called.
// In this sample code we turn around and immediately to a DNSServiceResolve() to resolve that service name
// to find its target host, port, and txtinfo, but a normal browing application would just display the name.
// Resolving every single thing you find can be quite hard on the network, so you shouldn't do this
// in a real application. Defer resolving until the client has picked which instance from the
// long list of services is the one they want to use, and then resolve only that one.
static void FoundInstance(DNSServiceRef client, DNSServiceFlags flags, uint32_t interface, DNSServiceErrorType errorCode,
const char *replyName, const char *replyType, const char *replyDomain, void *context)
{
#pragma unused(client, interface, errorCode)
SearcherServices *services = (SearcherServices *)context;
linkedServiceInfo *info;
if (!services) { DebugStr("\pFoundInstance: services is NULL"); return; }
info = (linkedServiceInfo *)OTAllocMem(sizeof(linkedServiceInfo));
if (!info) { services->lostRecords = true; return; }
info->services = services;
strcpy(info->name, replyName);
strcpy(info->type, replyType);
strcpy(info->domn, replyDomain);
info->text[0] = 0;
info->add = (flags & kDNSServiceFlagsAdd) ? true : false;
info->dom = false;
if (!info->add) // If TTL == 0 we're deleting a service,
OTLIFOEnqueue(&services->serviceinfolist, &info->link);
else // else we're adding a new service
DNSServiceResolve(&info->sdRef, 0, 0, info->name, info->type, info->domn, FoundInstanceInfo, info);
}
// YieldSomeTime() just cooperatively yields some time to other processes running on classic Mac OS
static Boolean YieldSomeTime(UInt32 milliseconds)
{
extern Boolean SIOUXQuitting;
EventRecord e;
WaitNextEvent(everyEvent, &e, milliseconds / 17, NULL);
SIOUXHandleOneEvent(&e);
return(SIOUXQuitting);
}
int main()
{
OSStatus err;
void *tempmem;
DNSServiceRef sdRef;
DNSServiceErrorType dse;
SIOUXSettings.asktosaveonclose = false;
SIOUXSettings.userwindowtitle = "\pMulticast DNS Searcher";
SIOUXSettings.rows = 40;
SIOUXSettings.columns = 160;
printf("DNS-SD Search Client\n\n");
printf("This software reports errors using MacsBug breaks,\n");
printf("so if you don't have MacsBug installed your Mac may crash.\n\n");
printf("******************************************************************************\n\n");
if (DNSServiceBrowse == (void*)kUnresolvedCFragSymbolAddress)
{
printf("Before you can use mDNS/DNS-SD clients, you need to place the \n");
printf("\"Multicast DNS & DNS-SD\" Extension in the Extensions Folder and restart\n");
return(-1);
}
err = InitOpenTransport();
if (err) { printf("InitOpenTransport failed %d", err); return(err); }
// Make sure OT has a large enough memory pool for us to draw from at OTNotifier (interrupt) time
tempmem = OTAllocMem(0x10000);
if (tempmem) OTFreeMem(tempmem);
else printf("**** Warning: OTAllocMem couldn't pre-allocate 64K for us.\n");
services.serviceinfolist.fHead = NULL;
services.headerPrinted = false;
services.lostRecords = false;
printf("Sending mDNS service lookup queries and waiting for responses...\n\n");
dse = DNSServiceBrowse(&sdRef, 0, 0, "_http._tcp", "", FoundInstance, &services);
if (dse == kDNSServiceErr_NoError)
{
while (!YieldSomeTime(35))
{
if (services.serviceinfolist.fHead)
PrintServiceInfo(&services);
if (services.lostRecords)
{
services.lostRecords = false;
printf("**** Warning: Out of memory: Records have been missed.\n");
}
}
}
DNSServiceRefDeallocate(sdRef);
CloseOpenTransport();
return(0);
}

View File

@ -1,160 +0,0 @@
// ShowInitIcon - version 1.0.1, May 30th, 1995
// This code is intended to let INIT writers easily display an icon at startup time.
// View in Geneva 9pt, 4-space tabs
// Written by: Peter N Lewis <peter@mail.peter.com.au>, Jim Walker <JWWalker@aol.com>
// and François Pottier <pottier@dmi.ens.fr>, with thanks to previous ShowINIT authors.
// Send comments and bug reports to François Pottier.
// This version features:
// - Short and readable code.
// - Correctly wraps around when more than one row of icons has been displayed.
// - works with System 6
// - Built with Universal Headers & CodeWarrior. Should work with other headers/compilers.
#include <Memory.h>
#include <Resources.h>
#include <Icons.h>
#include <OSUtils.h>
#include "ShowInitIcon.h"
// You should set SystemSixOrLater in your headers to avoid including glue for SysEnvirons.
// ---------------------------------------------------------------------------------------------------------------------
// Set this flag to 1 if you want to compile this file into a stand-alone resource (see note below).
// Set it to 0 if you want to include this source file into your INIT project.
#if 0
#define ShowInitIcon main
#endif
// ---------------------------------------------------------------------------------------------------------------------
// The ShowINIT mechanism works by having each INIT read/write data from these globals.
// The MPW C compiler doesn't accept variables declared at an absolute address, so I use these macros instead.
// Only one macro is defined per variable; there is no need to define a Set and a Get accessor like in <LowMem.h>.
#define LMVCheckSum (*(unsigned short*) 0x928)
#define LMVCoord (*( short*) 0x92A)
#define LMHCoord (*( short*) 0x92C)
#define LMHCheckSum (*(unsigned short*) 0x92E)
// ---------------------------------------------------------------------------------------------------------------------
// Prototypes for the subroutines. The main routine comes first; this is necessary to make THINK C's "Custom Header" option work.
static unsigned short CheckSum (short x);
static void ComputeIconRect (Rect* iconRect, Rect* screenBounds);
static void AdvanceIconPosition (Rect* iconRect);
static void DrawBWIcon (short iconID, Rect *iconRect);
// ---------------------------------------------------------------------------------------------------------------------
// Main routine.
typedef struct {
QDGlobals qd; // Storage for the QuickDraw globals
long qdGlobalsPtr; // A5 points to this place; it will contain a pointer to qd
} QDStorage;
pascal void ShowInitIcon (short iconFamilyID, Boolean advance)
{
long oldA5; // Original value of register A5
QDStorage qds; // Fake QD globals
CGrafPort colorPort;
GrafPort bwPort;
Rect destRect;
SysEnvRec environment; // Machine configuration.
oldA5 = SetA5((long) &qds.qdGlobalsPtr); // Tell A5 to point to the end of the fake QD Globals
InitGraf(&qds.qd.thePort); // Initialize the fake QD Globals
SysEnvirons(curSysEnvVers, &environment); // Find out what kind of machine this is
ComputeIconRect(&destRect, &qds.qd.screenBits.bounds); // Compute where the icon should be drawn
if (environment.systemVersion >= 0x0700 && environment.hasColorQD) {
OpenCPort(&colorPort);
PlotIconID(&destRect, atNone, ttNone, iconFamilyID);
CloseCPort(&colorPort);
}
else {
OpenPort(&bwPort);
DrawBWIcon(iconFamilyID, &destRect);
ClosePort(&bwPort);
}
if (advance)
AdvanceIconPosition (&destRect);
SetA5(oldA5); // Restore A5 to its previous value
}
// ---------------------------------------------------------------------------------------------------------------------
// A checksum is used to make sure that the data in there was left by another ShowINIT-aware INIT.
static unsigned short CheckSum (short x)
{
return (unsigned short)(((x << 1) | (x >> 15)) ^ 0x1021);
}
// ---------------------------------------------------------------------------------------------------------------------
// ComputeIconRect computes where the icon should be displayed.
static void ComputeIconRect (Rect* iconRect, Rect* screenBounds)
{
if (CheckSum(LMHCoord) != LMHCheckSum) // If we are first, we need to initialize the shared data.
LMHCoord = 8;
if (CheckSum(LMVCoord) != LMVCheckSum)
LMVCoord = (short)(screenBounds->bottom - 40);
if (LMHCoord + 34 > screenBounds->right) { // Check whether we must wrap
iconRect->left = 8;
iconRect->top = (short)(LMVCoord - 40);
}
else {
iconRect->left = LMHCoord;
iconRect->top = LMVCoord;
}
iconRect->right = (short)(iconRect->left + 32);
iconRect->bottom = (short)(iconRect->top + 32);
}
// AdvanceIconPosition updates the shared global variables so that the next extension will draw its icon beside ours.
static void AdvanceIconPosition (Rect* iconRect)
{
LMHCoord = (short)(iconRect->left + 40); // Update the shared data
LMVCoord = iconRect->top;
LMHCheckSum = CheckSum(LMHCoord);
LMVCheckSum = CheckSum(LMVCoord);
}
// DrawBWIcon draws the 'ICN#' member of the icon family. It works under System 6.
static void DrawBWIcon (short iconID, Rect *iconRect)
{
Handle icon;
BitMap source, destination;
GrafPtr port;
icon = Get1Resource('ICN#', iconID);
if (icon != NULL) {
HLock(icon);
// Prepare the source and destination bitmaps.
source.baseAddr = *icon + 128; // Mask address.
source.rowBytes = 4;
SetRect(&source.bounds, 0, 0, 32, 32);
GetPort(&port);
destination = port->portBits;
// Transfer the mask.
CopyBits(&source, &destination, &source.bounds, iconRect, srcBic, nil);
// Then the icon.
source.baseAddr = *icon;
CopyBits(&source, &destination, &source.bounds, iconRect, srcOr, nil);
}
}
// ---------------------------------------------------------------------------------------------------------------------
// Notes
// Checking for PlotIconID:
// We (PNL) now check for system 7 and colour QD, and use colour graf ports and PlotIconID only if both are true
// Otherwise we use B&W grafport and draw using PlotBWIcon.

View File

@ -1,20 +0,0 @@
#ifndef __ShowInitIcon__
#define __ShowInitIcon__
#include <Types.h>
// Usage: pass the ID of your icon family (ICN#/icl4/icl8) to have it drawn in the right spot.
// If 'advance' is true, the next INIT icon will be drawn to the right of your icon. If it is false, the next INIT icon will overwrite
// yours. You can use it to create animation effects by calling ShowInitIcon several times with 'advance' set to false.
#ifdef __cplusplus
extern "C" {
#endif
pascal void ShowInitIcon (short iconFamilyID, Boolean advance);
#ifdef __cplusplus
}
#endif
#endif /* __ShowInitIcon__ */

View File

@ -1,217 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h> // For printf()
#include <string.h> // For strlen() etc.
#include <Events.h> // For WaitNextEvent()
#include <SIOUX.h> // For SIOUXHandleOneEvent()
#include "mDNSEmbeddedAPI.h" // Defines the interface to the client layer above
#include "mDNSMacOS9.h" // Defines the specific types needed to run mDNS on this platform
// These don't have to be globals, but their memory does need to remain valid for as
// long as the search is going on. They are declared as globals here for simplicity.
static mDNS m;
static mDNS_PlatformSupport p;
static ServiceRecordSet p1, p2;
static AuthRecord availRec1, availRec2;
static Boolean availRec2Active;
// This sample code just calls mDNS_RenameAndReregisterService to automatically pick a new
// unique name for the service. For a device such as a printer, this may be appropriate.
// For a device with a user interface, and a screen, and a keyboard, the appropriate
// response may be to prompt the user and ask them to choose a new name for the service.
mDNSlocal void Callback(mDNS *const m, ServiceRecordSet *const sr, mStatus result)
{
switch (result)
{
case mStatus_NoError: debugf("Callback: %##s Name Registered", sr->RR_SRV.resrec.name.c); break;
case mStatus_NameConflict: debugf("Callback: %##s Name Conflict", sr->RR_SRV.resrec.name.c); break;
case mStatus_MemFree: debugf("Callback: %##s Memory Free", sr->RR_SRV.resrec.name.c); break;
default: debugf("Callback: %##s Unknown Result %d", sr->RR_SRV.resrec.name.c, result); break;
}
if (result == mStatus_NameConflict) mDNS_RenameAndReregisterService(m, sr, mDNSNULL);
}
// RegisterService() is a simple wrapper function which takes C string
// parameters, converts them to domainname parameters, and calls mDNS_RegisterService()
mDNSlocal void RegisterService(mDNS *m, ServiceRecordSet *recordset,
UInt16 PortAsNumber, const char txtinfo[],
const domainlabel *const n, const char type[], const char domain[])
{
domainname t;
domainname d;
char buffer[MAX_ESCAPED_DOMAIN_NAME];
UInt8 txtbuffer[512];
MakeDomainNameFromDNSNameString(&t, type);
MakeDomainNameFromDNSNameString(&d, domain);
if (txtinfo)
{
strncpy((char*)txtbuffer+1, txtinfo, sizeof(txtbuffer)-1);
txtbuffer[0] = (UInt8)strlen(txtinfo);
}
else
txtbuffer[0] = 0;
mDNS_RegisterService(m, recordset,
n, &t, &d, // Name, type, domain
mDNSNULL, mDNSOpaque16fromIntVal(PortAsNumber),
txtbuffer, (mDNSu16)(1+txtbuffer[0]), // TXT data, length
mDNSNULL, 0, // Subtypes (none)
mDNSInterface_Any, // Interface ID
Callback, mDNSNULL, 0); // Callback, context, flags
ConvertDomainNameToCString(recordset->RR_SRV.resrec.name, buffer);
printf("Made Service Records for %s\n", buffer);
}
// RegisterFakeServiceForTesting() simulates the effect of services being registered on
// dynamically-allocated port numbers. No real service exists on that port -- this is just for testing.
mDNSlocal void RegisterFakeServiceForTesting(mDNS *m, ServiceRecordSet *recordset, const char txtinfo[],
const char name[], const char type[], const char domain[])
{
static UInt16 NextPort = 0xF000;
domainlabel n;
MakeDomainLabelFromLiteralString(&n, name);
RegisterService(m, recordset, NextPort++, txtinfo, &n, type, domain);
}
// Done once on startup, and then again every time our address changes
mDNSlocal OSStatus mDNSResponderTestSetup(mDNS *m)
{
char buffer[MAX_ESCAPED_DOMAIN_NAME];
mDNSv4Addr ip = m->HostInterfaces->ip.ip.v4;
ConvertDomainNameToCString(&m->MulticastHostname, buffer);
printf("Name %s\n", buffer);
printf("IP %d.%d.%d.%d\n", ip.b[0], ip.b[1], ip.b[2], ip.b[3]);
printf("\n");
printf("Registering Service Records\n");
// Create example printer discovery records
//static ServiceRecordSet p1, p2;
RegisterFakeServiceForTesting(m, &p1, "", "One", "_raop._tcp.", "local.");
RegisterFakeServiceForTesting(m, &p2, "", "Two", "_raop._tcp.", "local.");
return(kOTNoError);
}
mDNSlocal void AvailCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
{
Boolean *b = (Boolean *)rr->RecordContext;
(void)m; // Unused
// Signal that our record is now free for re-use
if (result == mStatus_MemFree) *b = false;
}
mDNSlocal OSStatus mDNSResponderSetAvail(mDNS *m, AuthRecord *rr, ServiceRecordSet *sr)
{
// 1. Initialize required fields of AuthRecord
// 2. Set name of subtype PTR record to our special subtype name denoting "available" instances
// 3. Set target of subtype PTR record to point to our SRV record (exactly the same as the main service PTR record)
// 4. And register it
mDNS_SetupResourceRecord(rr, mDNSNULL, mDNSInterface_Any, kDNSType_PTR, 2*3600, kDNSRecordTypeShared, AvailCallback, &availRec2Active);
MakeDomainNameFromDNSNameString(rr->resrec.name, "a._sub._raop._tcp.local.");
AssignDomainName(&rr->resrec.rdata->u.name, sr->RR_SRV.resrec.name);
return(mDNS_Register(m, rr));
}
// YieldSomeTime() just cooperatively yields some time to other processes running on classic Mac OS
mDNSlocal Boolean YieldSomeTime(UInt32 milliseconds)
{
extern Boolean SIOUXQuitting;
EventRecord e;
WaitNextEvent(everyEvent, &e, milliseconds / 17, NULL);
SIOUXHandleOneEvent(&e);
return(SIOUXQuitting);
}
int main()
{
mStatus err;
Boolean DoneSetup = false;
mDNSs32 nextAvail, nextBusy;
SIOUXSettings.asktosaveonclose = false;
SIOUXSettings.userwindowtitle = "\pMulticast DNS Responder";
printf("Multicast DNS Responder\n\n");
printf("This software reports errors using MacsBug breaks,\n");
printf("so if you don't have MacsBug installed your Mac may crash.\n\n");
printf("******************************************************************************\n");
err = InitOpenTransport();
if (err) { debugf("InitOpenTransport failed %d", err); return(err); }
err = mDNS_Init(&m, &p, mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize,
mDNS_Init_AdvertiseLocalAddresses, mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
if (err) return(err);
while (!YieldSomeTime(35))
{
#if MDNS_ONLYSYSTEMTASK
// For debugging, use "#define MDNS_ONLYSYSTEMTASK 1" and call mDNSPlatformIdle() periodically.
// For shipping code, don't define MDNS_ONLYSYSTEMTASK, and you don't need to call mDNSPlatformIdle()
extern void mDNSPlatformIdle(mDNS *const m);
mDNSPlatformIdle(&m); // Only needed for debugging version
#endif
if (m.mDNSPlatformStatus == mStatus_NoError && !DoneSetup)
{
DoneSetup = true;
printf("\nListening for mDNS queries...\n");
mDNSResponderTestSetup(&m);
mDNSResponderSetAvail(&m, &availRec1, &p1);
availRec2Active = false;
nextAvail = mDNS_TimeNow(&m) + mDNSPlatformOneSecond * 10;
nextBusy = mDNS_TimeNow(&m) + mDNSPlatformOneSecond * 15;
}
if (DoneSetup)
{
// We check availRec2.RecordType because we don't want to re-register this record
// if the previous mDNS_Deregister() has not yet completed
if (mDNS_TimeNow(&m) - nextAvail > 0 && !availRec2Active)
{
printf("Setting Two now available\n");
availRec2Active = true;
mDNSResponderSetAvail(&m, &availRec2, &p2);
nextAvail = nextBusy + mDNSPlatformOneSecond * 10;
}
else if (mDNS_TimeNow(&m) - nextBusy > 0)
{
printf("Setting Two now busy\n");
mDNS_Deregister(&m, &availRec2);
nextBusy = nextAvail + mDNSPlatformOneSecond * 5;
}
}
}
if (p1.RR_SRV.resrec.RecordType) mDNS_DeregisterService(&m, &p1);
if (p2.RR_SRV.resrec.RecordType) mDNS_DeregisterService(&m, &p2);
if (availRec1.resrec.RecordType) mDNS_Deregister(&m, &availRec1);
if (availRec2Active) mDNS_Deregister(&m, &availRec2);
mDNS_Close(&m);
return(0);
}

Binary file not shown.

View File

@ -1,63 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Define the required CFM Shared Library entry and exit points
#include <CodeFragments.h>
#include "mDNSEmbeddedAPI.h" // Defines the interface to the client layer above
#include "mDNSMacOS9.h" // Defines the specific types needed to run mDNS on this platform
mDNS mDNSStorage;
static mDNS_PlatformSupport PlatformSupportStorage;
// Start off with a default cache of 16K (about 100 records)
#define RR_CACHE_SIZE ((16*1024) / sizeof(CacheRecord))
static CacheEntity rrcachestorage[RR_CACHE_SIZE];
mDNSlocal void mDNS_StatusCallback(mDNS *const m, mStatus result)
{
if (result == mStatus_GrowCache)
{
// Allocate another chunk of cache storage
CacheEntity *storage = OTAllocMem(sizeof(CacheEntity) * RR_CACHE_SIZE);
if (storage) mDNS_GrowCache(m, storage, RR_CACHE_SIZE);
}
}
extern pascal OSErr mDNS_CFMInit(const CFragInitBlock *theInitBlock);
pascal OSErr mDNS_CFMInit(const CFragInitBlock *theInitBlock)
{
extern pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
__initialize(theInitBlock); // MUST do this first!
{
mStatus err;
THz oldZone = GetZone();
SetZone(SystemZone());
LogMsg("mDNS/DNS-SD with Macsbug breaks -- do not ship this version to customers");
err = mDNS_Init(&mDNSStorage, &PlatformSupportStorage, rrcachestorage, RR_CACHE_SIZE,
mDNS_Init_AdvertiseLocalAddresses, mDNS_StatusCallback, mDNS_Init_NoInitCallbackContext);
SetZone(oldZone);
return((OSErr)err);
}
}
extern void mDNS_CFMTerm(void);
void mDNS_CFMTerm(void)
{
extern pascal void __terminate(void);
LogMsg("mDNS_CFMTerm");
mDNS_Close(&mDNSStorage);
__terminate();
}

View File

@ -1,68 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <Resources.h>
#include <CodeFragments.h>
#include "ShowInitIcon.h"
extern pascal OSErr FragRegisterFileLibs(ConstFSSpecPtr fss, Boolean unregister);
extern void main(void)
{
OSStatus err;
FCBPBRec fcbPB;
FSSpec fss;
// 1. Show our "icon march" icon
ShowInitIcon(128, true);
// 2. Find our FSSpec
fss.name[0] = 0;
fcbPB.ioNamePtr = fss.name;
fcbPB.ioVRefNum = 0;
fcbPB.ioRefNum = (short)CurResFile();
fcbPB.ioFCBIndx = 0;
err = PBGetFCBInfoSync(&fcbPB);
// 3. Tell CFM that we're a CFM library container file
fss.vRefNum = fcbPB.ioFCBVRefNum;
fss.parID = fcbPB.ioFCBParID;
if (err == noErr) err = FragRegisterFileLibs(&fss, false);
// 4. Now that CFM knows we're a library container, tell it to go and get our library
if (err == noErr)
{
CFragConnectionID c;
Ptr m;
Str255 e;
THz oldZone = GetZone();
SetZone(SystemZone());
err = GetSharedLibrary("\pDarwin;mDNS", kPowerPCCFragArch, kLoadCFrag, &c, &m, e);
SetZone(oldZone);
}
}
// There's no CFM stub library for the FragRegisterFileLibs() call, so we'll make our own
#if __ide_target("FragRegisterFileLibsStub")
#pragma export on
pascal OSErr FragRegisterFileLibs(ConstFSSpecPtr fss, Boolean unregister)
{
(void)fss; // Unused
(void)unregister; // Unused
return(0);
}
#endif

View File

@ -1,197 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __TYPES.R__
#include "Types.r"
#endif
/* Format is :
* Two-char BCD major version (0-99)
* One-char BCD minor version, One-char BCD bugfix version (0-9, 0-9)
* development/alpha/beta/final
* One-byte non-final build number (0-255)
* Version numbers can therefore range from 0.0.0 to 99.9.9,
* with a following build stage and build number (e.g. 2.0.1 beta 219)
*/
resource 'vers' (1, purgeable)
{
0x01, 0x00, alpha, 130, verUS,
"1.0a130",
"Multicast DNS & DNS Service Discovery 1.0a130"
};
resource 'vers' (2, purgeable)
{
0x01, 0x00, alpha, 130, verUS,
"1.0a130",
"developer.apple.com/darwin/projects/bonjour/"
};
/* We need to load OT, so make sure the system heap has enough space for it */
type 'sysz' { longint; };
resource 'sysz' (0, purgeable) { 2500000 };
resource 'BNDL' (128, purgeable, protected) {
'mDNS',
0,
{ /* array TypeArray: 2 elements */
/* [1] */
'FREF',
{ /* array IDArray: 1 elements */
/* [1] */
0, 128
},
/* [2] */
'ICN#',
{ /* array IDArray: 1 elements */
/* [1] */
0, 128
}
}
};
resource 'FREF' (128, purgeable, protected) {
'INIT',
0,
""
};
resource 'icl8' (128, purgeable, protected) {
$"FDFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF"
$"FFFF FFFF FFFF FFFF FFFF FFFF FD00 0000"
$"FF00 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 0000 0000 0000 00F6 FF00 0000"
$"FF00 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6"
$"F6F6 F6F6 F6F6 F6F6 F6F6 F6F9 FF00 0000"
$"FF00 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6"
$"F6F6 F6F6 F6F6 F6F6 F6F6 F6F9 FD00 0000"
$"FF00 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6"
$"F6F6 F6F6 F6F6 F6F6 F6F6 F6F9 FE00 0000"
$"FF00 F6F6 F6F6 F6F6 F62B 07F6 F6F6 F6F6"
$"F6F6 F6F6 F6F6 F6F6 F6F6 F6F9 FE00 0000"
$"FF00 F6F6 F6F6 F6F6 3A16 402B F7F6 F6F6"
$"F6F6 F656 F9F9 F956 2BF6 F6F9 FE00 0000"
$"FF00 F6F6 F6F6 2B08 4116 4008 F8FA 2BF6"
$"F6F7 FAFA FA81 FAFA FAF7 F6F9 FE00 0000"
$"FF00 F9F6 F62B F92B 163A 172B F881 FAF6"
$"2BF8 F6F6 2BF7 8181 FA81 F6F9 FE00 FD00"
$"FF00 FFF9 F6F9 F9F8 2B2C 2BF6 F6F6 F8FA"
$"2BF6 F6F6 F6F6 F781 F956 F8F9 FEFD FFFD"
$"FFFF 00FE F5FA FA81 F7F6 F6F6 F6F6 F656"
$"56F6 F6F6 F6F6 F62B 2B2B F6F9 FEFF 00FF"
$"0000 00FF F5FA FAFA F6F6 F6F6 F6F6 2BF6"
$"F7F8 F6F6 F6F6 F607 3A16 39F9 FF00 F9FF"
$"0000 00FF 00FA 81FA F6F6 F6F6 F62B 2BF6"
$"F6F8 F6F6 F6F6 F633 1C3B 1CF6 F6F6 F9FF"
$"0000 00FE 0056 81FA F6F6 F6F6 F6F8 F6F6"
$"F6F6 F8F6 F6F6 F62C 163A 3AF6 F6F6 F9FF"
$"0000 00FE 00F6 8181 2BF6 F6F6 F72B F6F6"
$"F6F6 F62B F6F6 2B2B 2C32 F6F6 F6F6 F9FF"
$"0000 00FE 00F6 2BFA 81F6 F6F6 F9F6 F6F6"
$"F6F6 F62B F6F7 FA81 F8F6 F6F6 F6F6 F9FF"
$"0000 00FE 00F6 F6F6 F7F9 F72B F9F6 F6F6"
$"F62B F756 F9FA F9F7 F6F6 F6F6 F6F6 F9FF"
$"0000 00FE 00F6 F6F6 F6F6 F6F9 F82B 2BF7"
$"F7F7 F72B F8F6 F6F6 F6F6 F6F6 F6F6 F9FF"
$"0000 00FE 00F6 F6F6 F6F6 F681 2BF6 F6F6"
$"F6F6 F6F6 F7F6 F6F6 F6F6 F6F6 F6F6 F9FF"
$"0000 00FE 00F6 F6F6 F6F6 2B81 F7F6 F6F6"
$"F6F6 F6F6 562B F6F6 F6F6 F6F6 F9F6 F9FF"
$"0000 00FE 00F6 F6F6 F6F6 F7FB F7F6 F6F6"
$"F6F6 F6F6 FAF7 F6F6 F6F6 F6F9 FEF9 F9FF"
$"FFFF 00FE 00F6 F6F6 F6F6 F7F7 2BF6 F6F6"
$"F6F6 F6F8 81F7 F6F6 F6F6 F6F9 FEFF F9FF"
$"FF00 FF00 00F6 F6F6 F6F6 F60E 3A16 32F6"
$"F6F6 56FA 812B F6F6 F6F6 F6F9 FEFD FFFD"
$"FF00 0000 F6F6 F6F6 F6F6 F640 1640 16F6"
$"F9F9 FA81 F9F6 F6F6 F6F6 F6F9 FE00 FD00"
$"FF00 F6F6 F6F6 F6F6 F6F6 F633 173A 332B"
$"FAFA 8181 2BF6 F6F6 F6F6 F6F9 FE00 0000"
$"FF00 F6F6 F6F6 F6F6 F6F6 F6F6 3232 F6F9"
$"8181 FA2B F6F6 F6F6 F6F6 F6F9 FE00 0000"
$"FF00 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 2BF8"
$"F82B F6F6 F6F6 F6F6 F6F6 F6F9 FE00 0000"
$"FF00 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6"
$"F6F6 F6F6 F6F6 F6F6 F6F6 F6F9 FE00 0000"
$"FF00 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6"
$"F6F6 F6F6 F6F6 F6F6 F6F6 F6F9 FD00 0000"
$"FF00 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6"
$"F6F6 F6F6 F6F6 F6F6 F6F6 F6F9 FF00 0000"
$"FFF6 F9F9 F9F9 F9F9 F9F9 F9F9 F9F9 F9F9"
$"F9F9 F9F9 F9F9 F9F9 F9F9 F9F9 FF00 0000"
$"FDFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF"
$"FFFF FFFF FFFF FFFF FFFF FFFF FD"
};
data 'mDNS' (0, "Owner resource") {
$"0644 6172 7769 6E" /* .Darwin */
};
resource 'ICN#' (128) {
{ /* array: 2 elements */
/* [1] */
$"FFFF FFF8 8000 0008 8000 0008 8000 0008"
$"8000 0008 80E0 0408 81FC 3F88 83FE 7FC8"
$"87FF EFEA A7E3 83EF D781 81ED 1F02 C1E9"
$"1706 61F1 1704 21E1 178C 33C1 13C8 1781"
$"10F8 FF01 101F F801 1018 0801 1038 0C01"
$"1038 0C09 D03C 1C0D A01E 7C0F 801F F80A"
$"801F F808 800F F008 8003 C008 8000 0008"
$"8000 0008 8000 0008 8000 0008 FFFF FFF8",
/* [2] */
$"FFFF FFF8 FFFF FFF8 FFFF FFF8 FFFF FFF8"
$"FFFF FFF8 FFFF FFF8 FFFF FFF8 FFFF FFF8"
$"FFFF FFFA FFFF FFFF DFFF FFFF 1FFF FFFF"
$"1FFF FFFF 1FFF FFFF 1FFF FFFF 1FFF FFFF"
$"1FFF FFFF 1FFF FFFF 1FFF FFFF 1FFF FFFF"
$"1FFF FFFF DFFF FFFF FFFF FFFF FFFF FFFA"
$"FFFF FFF8 FFFF FFF8 FFFF FFF8 FFFF FFF8"
$"FFFF FFF8 FFFF FFF8 FFFF FFF8 FFFF FFF8"
}
};
resource 'ics#' (128, purgeable) {
{ /* array: 2 elements */
/* [1] */
$"FFFE 8002 8002 8C02 DE73 D19B 5299 5451"
$"4C61 47C1 C443 C483 8702 8302 8002 FFFE",
/* [2] */
$"FFFE FFFE FFFE FFFE FFFF FFFF 7FFF 7FFF"
$"7FFF 7FFF FFFF FFFF FFFE FFFE FFFE FFFE"
}
};
resource 'ics8' (128) {
$"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FF00"
$"FFF6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 FD00"
$"FFF6 F6F6 32F6 F6F6 F6F6 F7F7 F6F6 FF00"
$"FFF6 F632 2233 81F6 2B56 81AC FBF6 FF00"
$"FFFE FAF9 2CF6 2BFA 2BF6 F6F8 FAF8 FEFF"
$"FFFD FCFA F6F6 F62B F8F6 F6F6 3333 FEFF"
$"00FE 81F9 F6F6 2BF6 F62B F6F6 4040 F6FF"
$"00FF 2BFB 2BF6 F7F6 F62B F6F9 32F6 F6FF"
$"00FE F6F6 F7F8 F7F6 2BF8 56F8 F6F6 F6FF"
$"00FE F6F6 F6FA F6F6 F6F6 F7F6 F6F6 F6FF"
$"FFFE F6F6 F6FA 2BF6 F6F6 FAF6 F6F6 FEFF"
$"FFFE F6F6 F632 3AF6 2BF9 81F6 F6F6 FEFF"
$"FFF6 F6F6 F632 4632 FCAC F7F6 F6F6 FE00"
$"FFF6 F6F6 F6F6 F6F8 562B F6F6 F6F6 FE00"
$"FFF6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 FE00"
$"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FF"
};

View File

@ -1,687 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdarg.h> // For va_list support
#include <LowMem.h> // For LMGetCurApName()
#include <TextUtils.h> // For smSystemScript
#include <UnicodeConverter.h> // For ConvertFromPStringToUnicode()
#include "mDNSEmbeddedAPI.h" // Defines the interface provided to the client layer above
#include "mDNSMacOS9.h" // Defines the specific types needed to run mDNS on this platform
// ***************************************************************************
// Constants
static const TSetBooleanOption kReusePortOption =
{ kOTBooleanOptionSize, INET_IP, IP_REUSEPORT, 0, true };
// IP_RCVDSTADDR with TSetByteOption/kOTOneByteOptionSize works on OS 9, OS X Classic, and OS 9 Carbon,
// but gives error #-3151 (kOTBadOptionErr) on OS X Carbon.
// If we instead use TSetBooleanOption/kOTBooleanOptionSize then OTOptionManagement on OS X Carbon
// no longer returns -3151 but it still doesn't actually work -- no destination addresses
// are delivered by OTRcvUData. I think it's just a bug in OS X Carbon.
static const TSetByteOption kRcvDestAddrOption =
{ kOTOneByteOptionSize, INET_IP, IP_RCVDSTADDR, 0, true };
//static const TSetBooleanOption kRcvDestAddrOption =
// { kOTBooleanOptionSize, INET_IP, IP_RCVDSTADDR, 0, true };
static const TSetByteOption kSetUnicastTTLOption =
{ kOTOneByteOptionSize, INET_IP, IP_TTL, 0, 255 };
static const TSetByteOption kSetMulticastTTLOption =
{ kOTOneByteOptionSize, INET_IP, IP_MULTICAST_TTL, 0, 255 };
static const TIPAddMulticastOption kAddLinkMulticastOption =
{ sizeof(TIPAddMulticastOption), INET_IP, IP_ADD_MEMBERSHIP, 0, { 224, 0, 0,251 }, { 0,0,0,0 } };
//static const TIPAddMulticastOption kAddAdminMulticastOption =
// { sizeof(TIPAddMulticastOption), INET_IP, IP_ADD_MEMBERSHIP, 0, { 239,255,255,251 }, { 0,0,0,0 } };
// Bind endpoint to port number. Don't specify any specific IP address --
// we want to receive unicasts on all interfaces, as well as multicasts.
typedef struct { OTAddressType fAddressType; mDNSIPPort fPort; mDNSv4Addr fHost; UInt8 fUnused[8]; } mDNSInetAddress;
//static const mDNSInetAddress mDNSPortInetAddress = { AF_INET, { 0,0 }, { 0,0,0,0 } }; // For testing legacy client support
#define MulticastDNSPortAsNumber 5353
static const mDNSInetAddress mDNSPortInetAddress = { AF_INET, { MulticastDNSPortAsNumber >> 8, MulticastDNSPortAsNumber & 0xFF }, { 0,0,0,0 } };
static const TBind mDNSbindReq = { sizeof(mDNSPortInetAddress), sizeof(mDNSPortInetAddress), (UInt8*)&mDNSPortInetAddress, 0 };
static const TNetbuf zeroTNetbuf = { 0 };
// ***************************************************************************
// Functions
mDNSlocal void SafeDebugStr(unsigned char *buffer)
{
int i;
// Don't want semicolons in MacsBug messages -- they signify commands to execute
for (i=1; i<= buffer[0]; i++) if (buffer[i] == ';') buffer[i] = '.';
DebugStr(buffer);
}
#if MDNS_DEBUGMSGS
mDNSexport void debugf_(const char *format, ...)
{
unsigned char buffer[256];
va_list ptr;
va_start(ptr,format);
buffer[0] = (unsigned char)mDNS_vsnprintf((char*)buffer+1, 255, format, ptr);
va_end(ptr);
#if MDNS_ONLYSYSTEMTASK
buffer[1+buffer[0]] = 0;
fprintf(stderr, "%s\n", buffer+1);
fflush(stderr);
#else
SafeDebugStr(buffer);
#endif
}
#endif
#if MDNS_BUILDINGSHAREDLIBRARY >= 2
// When building the non-debug version of the Extension, intended to go on end-user systems, we don't want
// MacsBug breaks for *anything*, not even for the serious LogMsg messages that on OS X would be written to syslog
mDNSexport void LogMsg(const char *format, ...) { (void)format; }
#else
mDNSexport void LogMsg(const char *format, ...)
{
unsigned char buffer[256];
va_list ptr;
va_start(ptr,format);
buffer[0] = (unsigned char)mDNS_vsnprintf((char*)buffer+1, 255, format, ptr);
va_end(ptr);
#if MDNS_ONLYSYSTEMTASK
buffer[1+buffer[0]] = 0;
fprintf(stderr, "%s\n", buffer+1);
fflush(stderr);
#else
SafeDebugStr(buffer);
#endif
}
#endif
mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
mDNSInterfaceID InterfaceID, const mDNSAddr *dst, mDNSIPPort dstPort)
{
// Note: If we did multi-homing, we'd have to use the InterfaceID parameter to specify from which interface to send this response
#pragma unused(InterfaceID)
InetAddress InetDest;
TUnitData senddata;
if (dst->type != mDNSAddrType_IPv4) return(mStatus_NoError);
InetDest.fAddressType = AF_INET;
InetDest.fPort = dstPort.NotAnInteger;
InetDest.fHost = dst->ip.v4.NotAnInteger;
senddata.addr.maxlen = sizeof(InetDest);
senddata.addr.len = sizeof(InetDest);
senddata.addr.buf = (UInt8*)&InetDest;
senddata.opt = zeroTNetbuf;
senddata.udata.maxlen = (UInt32)((UInt8*)end - (UInt8*)msg);
senddata.udata.len = (UInt32)((UInt8*)end - (UInt8*)msg);
senddata.udata.buf = (UInt8*)msg;
return(OTSndUData(m->p->ep, &senddata));
}
mDNSlocal OSStatus readpacket(mDNS *m)
{
mDNSAddr senderaddr, destaddr;
mDNSInterfaceID interface;
mDNSIPPort senderport;
InetAddress sender;
char options[256];
DNSMessage packet;
TUnitData recvdata;
OTFlags flags = 0;
OSStatus err;
recvdata.addr.maxlen = sizeof(sender);
recvdata.addr.len = 0;
recvdata.addr.buf = (UInt8*)&sender;
recvdata.opt.maxlen = sizeof(options);
recvdata.opt.len = 0;
recvdata.opt.buf = (UInt8*)&options;
recvdata.udata.maxlen = sizeof(packet);
recvdata.udata.len = 0;
recvdata.udata.buf = (UInt8*)&packet;
err = OTRcvUData(m->p->ep, &recvdata, &flags);
if (err && err != kOTNoDataErr) debugf("OTRcvUData error %d", err);
if (err) return(err);
senderaddr.type = mDNSAddrType_IPv4;
senderaddr.ip.v4.NotAnInteger = sender.fHost;
senderport.NotAnInteger = sender.fPort;
destaddr.type = mDNSAddrType_IPv4;
destaddr.ip.v4 = zerov4Addr;
#if OTCARBONAPPLICATION
// IP_RCVDSTADDR is known to fail on OS X Carbon, so we'll just assume the packet was probably multicast
destaddr.ip.v4 = AllDNSLinkGroup_v4.ip.v4;
#endif
if (recvdata.opt.len)
{
TOption *c = nil;
while (1)
{
err = OTNextOption(recvdata.opt.buf, recvdata.opt.len, &c);
if (err || !c) break;
if (c->level == INET_IP && c->name == IP_RCVDSTADDR && c->len - kOTOptionHeaderSize == sizeof(destaddr.ip.v4))
mDNSPlatformMemCopy(&destaddr.ip.v4, c->value, sizeof(destaddr.ip.v4));
}
}
interface = m->HostInterfaces->InterfaceID;
if (flags & T_MORE) debugf("ERROR: OTRcvUData() buffer too small (T_MORE set)");
else if (recvdata.addr.len < sizeof(InetAddress)) debugf("ERROR: recvdata.addr.len (%d) too short", recvdata.addr.len);
else mDNSCoreReceive(m, &packet, recvdata.udata.buf + recvdata.udata.len, &senderaddr, senderport, &destaddr, MulticastDNSPort, interface);
return(err);
}
mDNSexport TCPSocket *mDNSPlatformTCPSocket(mDNS * const m, TCPSocketFlags flags, mDNSIPPort * port)
{
(void)m; // Unused
(void)flags; // Unused
(void)port; // Unused
return NULL;
}
mDNSexport TCPSocket *mDNSPlatformTCPAccept(TCPSocketFlags flags, int sd)
{
(void)flags; // Unused
(void)sd; // Unused
return NULL;
}
mDNSexport int mDNSPlatformTCPGetFD(TCPSocket *sock)
{
(void)sock; // Unused
return -1;
}
mDNSexport mStatus mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr * dst, mDNSOpaque16 dstport, mDNSInterfaceID InterfaceID,
TCPConnectionCallback callback, void * context)
{
(void)sock; // Unused
(void)dst; // Unused
(void)dstport; // Unused
(void)InterfaceID; // Unused
(void)callback; // Unused
(void)context; // Unused
return(mStatus_UnsupportedErr);
}
mDNSexport void mDNSPlatformTCPCloseConnection(TCPSocket *sd)
{
(void)sd; // Unused
}
mDNSexport long mDNSPlatformReadTCP(TCPSocket *sock, void *buf, unsigned long buflen, mDNSBool *closed)
{
(void)sock; // Unused
(void)buf; // Unused
(void)buflen; // Unused
(void)closed; // Unused
return(0);
}
mDNSexport long mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned long len)
{
(void)sock; // Unused
(void)msg; // Unused
(void)len; // Unused
return(0);
}
mDNSexport UDPSocket *mDNSPlatformUDPSocket(mDNS * const m, mDNSIPPort port)
{
(void)m; // Unused
(void)port; // Unused
return NULL;
}
mDNSexport void mDNSPlatformUDPClose(UDPSocket *sock)
{
(void)sock; // Unused
}
mDNSlocal void mDNSOptionManagement(mDNS *const m)
{
OSStatus err;
// Make sure the length in the TNetbuf agrees with the length in the TOptionHeader
m->p->optReq.opt.len = m->p->optBlock.h.len;
m->p->optReq.opt.maxlen = m->p->optBlock.h.len;
if (m->p->optReq.opt.maxlen < 4)
m->p->optReq.opt.maxlen = 4;
err = OTOptionManagement(m->p->ep, &m->p->optReq, NULL);
if (err) LogMsg("OTOptionManagement failed %d", err);
}
mDNSlocal void mDNSinitComplete(mDNS *const m, mStatus result)
{
m->mDNSPlatformStatus = result;
mDNSCoreInitComplete(m, mStatus_NoError);
}
mDNSlocal pascal void mDNSNotifier(void *contextPtr, OTEventCode code, OTResult result, void *cookie)
{
mDNS *const m = (mDNS *const)contextPtr;
if (!m) debugf("mDNSNotifier FATAL ERROR! No context");
switch (code)
{
case T_OPENCOMPLETE:
{
OSStatus err;
InetInterfaceInfo interfaceinfo;
if (result) { LogMsg("T_OPENCOMPLETE failed %d", result); mDNSinitComplete(m, result); return; }
//debugf("T_OPENCOMPLETE");
m->p->ep = (EndpointRef)cookie;
//debugf("OTInetGetInterfaceInfo");
// (In future may want to loop over all interfaces instead of just using kDefaultInetInterface)
err = OTInetGetInterfaceInfo(&interfaceinfo, kDefaultInetInterface);
if (err) { LogMsg("OTInetGetInterfaceInfo failed %d", err); mDNSinitComplete(m, err); return; }
// Make our basic standard host resource records (address, PTR, etc.)
m->p->interface.InterfaceID = (mDNSInterfaceID)&m->p->interface;
m->p->interface.ip.type = mDNSAddrType_IPv4;
m->p->interface.ip.ip.v4.NotAnInteger = interfaceinfo.fAddress;
m->p->interface.mask.type = mDNSAddrType_IPv4;
m->p->interface.mask.ip.v4.NotAnInteger = interfaceinfo.fNetmask;
m->p->interface.ifname[0] = 0;
m->p->interface.Advertise = m->AdvertiseLocalAddresses;
m->p->interface.McastTxRx = mDNStrue;
}
case T_OPTMGMTCOMPLETE:
case T_BINDCOMPLETE:
// IP_RCVDSTADDR is known to fail on OS X Carbon, so we don't want to abort for that error
// (see comment above at the definition of kRcvDestAddrOption)
#if OTCARBONAPPLICATION
if (result && m->p->mOTstate == mOT_RcvDestAddr)
LogMsg("Carbon IP_RCVDSTADDR option failed %d; continuing anyway", result);
else
#endif
if (result) { LogMsg("T_OPTMGMTCOMPLETE/T_BINDCOMPLETE %d failed %d", m->p->mOTstate, result); mDNSinitComplete(m, result); return; }
//LogMsg("T_OPTMGMTCOMPLETE/T_BINDCOMPLETE %d", m->p->mOTstate);
switch (++m->p->mOTstate)
{
case mOT_ReusePort: m->p->optBlock.b = kReusePortOption; mDNSOptionManagement(m); break;
case mOT_RcvDestAddr: m->p->optBlock.i = kRcvDestAddrOption; mDNSOptionManagement(m); break;
case mOT_SetUTTL: m->p->optBlock.i = kSetUnicastTTLOption; mDNSOptionManagement(m); break;
case mOT_SetMTTL: m->p->optBlock.i = kSetMulticastTTLOption; mDNSOptionManagement(m); break;
case mOT_LLScope: m->p->optBlock.m = kAddLinkMulticastOption; mDNSOptionManagement(m); break;
// case mOT_AdminScope: m->p->optBlock.m = kAddAdminMulticastOption; mDNSOptionManagement(m); break;
case mOT_Bind: OTBind(m->p->ep, (TBind*)&mDNSbindReq, NULL); break;
case mOT_Ready: mDNSinitComplete(m, mStatus_NoError);
// Can't do mDNS_RegisterInterface until *after* mDNSinitComplete has set m->mDNSPlatformStatus to mStatus_NoError
mDNS_RegisterInterface(m, &m->p->interface, mDNSfalse);
break;
default: LogMsg("Unexpected m->p->mOTstate %d", m->p->mOTstate-1);
}
break;
case T_DATA:
//debugf("T_DATA");
while (readpacket(m) == kOTNoError) continue; // Read packets until we run out
break;
case kOTProviderWillClose: LogMsg("kOTProviderWillClose"); break;
case kOTProviderIsClosed: // Machine is going to sleep, shutting down, or reconfiguring IP
LogMsg("kOTProviderIsClosed");
if (m->p->mOTstate == mOT_Ready)
{
m->p->mOTstate = mOT_Closed;
mDNS_DeregisterInterface(m, &m->p->interface, mDNSfalse);
}
if (m->p->ep) { OTCloseProvider(m->p->ep); m->p->ep = NULL; }
break; // Do we need to do anything?
default: debugf("mDNSNotifier: Unexpected OTEventCode %X", code);
break;
}
}
#if MDNS_ONLYSYSTEMTASK
static Boolean ONLYSYSTEMTASKevent;
static void *ONLYSYSTEMTASKcontextPtr;
static OTEventCode ONLYSYSTEMTASKcode;
static OTResult ONLYSYSTEMTASKresult;
static void *ONLYSYSTEMTASKcookie;
mDNSlocal pascal void CallmDNSNotifier(void *contextPtr, OTEventCode code, OTResult result, void *cookie)
{
ONLYSYSTEMTASKcontextPtr = contextPtr;
ONLYSYSTEMTASKcode = code;
ONLYSYSTEMTASKresult = result;
ONLYSYSTEMTASKcookie = cookie;
}
#else
mDNSlocal pascal void CallmDNSNotifier(void *contextPtr, OTEventCode code, OTResult result, void *cookie)
{
mDNS *const m = (mDNS *const)contextPtr;
if (!m) debugf("mDNSNotifier FATAL ERROR! No context");
if (m->p->nesting) LogMsg("CallmDNSNotifier ERROR! OTEnterNotifier is supposed to suppress notifier callbacks");
mDNSNotifier(contextPtr, code, result, cookie);
}
#endif
static OTNotifyUPP CallmDNSNotifierUPP;
mDNSlocal OSStatus mDNSOpenEndpoint(const mDNS *const m)
{
OSStatus err;
// m->optReq is pre-set to point to the shared m->optBlock
// m->optBlock is filled in by each OTOptionManagement call
m->p->optReq.opt.maxlen = sizeof(m->p->optBlock);
m->p->optReq.opt.len = sizeof(m->p->optBlock);
m->p->optReq.opt.buf = (UInt8*)&m->p->optBlock;
m->p->optReq.flags = T_NEGOTIATE;
// Open an endpoint and start answering queries
//printf("Opening endpoint now...\n");
m->p->ep = NULL;
m->p->mOTstate = mOT_Start;
err = OTAsyncOpenEndpoint(OTCreateConfiguration(kUDPName), 0, NULL, CallmDNSNotifierUPP, (void*)m);
if (err) { LogMsg("ERROR: OTAsyncOpenEndpoint(UDP) failed with error <%d>", err); return(err); }
return(kOTNoError);
}
// Define these here because they're not in older versions of OpenTransport.h
enum
{
xOTStackIsLoading = 0x27000001, /* Sent before Open Transport attempts to load the TCP/IP protocol stack.*/
xOTStackWasLoaded = 0x27000002, /* Sent after the TCP/IP stack has been successfully loaded.*/
xOTStackIsUnloading = 0x27000003 /* Sent before Open Transport unloads the TCP/IP stack.*/
};
static mDNS *ClientNotifierContext;
mDNSlocal pascal void ClientNotifier(void *contextPtr, OTEventCode code, OTResult result, void *cookie)
{
mDNS *const m = ClientNotifierContext;
#pragma unused(contextPtr) // Usually zero (except one in the 'xOTStackIsLoading' case)
#pragma unused(cookie) // Usually 'ipv4' (except for kOTPortNetworkChange)
#pragma unused(result) // Usually zero
switch (code)
{
case xOTStackIsLoading: break;
case xOTStackWasLoaded: if (m->p->mOTstate == mOT_Closed)
{
LogMsg("kOTStackWasLoaded: Re-opening endpoint");
if (m->p->ep)
LogMsg("kOTStackWasLoaded: ERROR: m->p->ep already set");
m->mDNSPlatformStatus = mStatus_Waiting;
m->p->mOTstate = mOT_Reset;
#if !MDNS_ONLYSYSTEMTASK
mDNSOpenEndpoint(m);
#endif
}
else
LogMsg("kOTStackWasLoaded (no action)");
break;
case xOTStackIsUnloading: break;
case kOTPortNetworkChange: break;
default: debugf("ClientNotifier unknown code %X, %X, %d", contextPtr, code, result); break;
}
}
#if TARGET_API_MAC_CARBON
mDNSlocal void GetUserSpecifiedComputerName(domainlabel *const namelabel)
{
CFStringRef cfs = CSCopyMachineName();
CFStringGetPascalString(cfs, namelabel->c, sizeof(*namelabel), kCFStringEncodingUTF8);
CFRelease(cfs);
}
#else
mDNSlocal OSStatus ConvertStringHandleToUTF8(const StringHandle machineName, UInt8 *const utf8, ByteCount maxlen)
{
OSStatus status;
TextEncoding utf8TextEncoding, SystemTextEncoding;
UnicodeMapping theMapping;
TextToUnicodeInfo textToUnicodeInfo;
ByteCount unicodelen = 0;
if (maxlen > 255) maxlen = 255; // Can't put more than 255 in a Pascal String
utf8TextEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault, kTextEncodingDefaultVariant, kUnicodeUTF8Format);
UpgradeScriptInfoToTextEncoding(smSystemScript, kTextLanguageDontCare, kTextRegionDontCare, NULL, &SystemTextEncoding);
theMapping.unicodeEncoding = utf8TextEncoding;
theMapping.otherEncoding = SystemTextEncoding;
theMapping.mappingVersion = kUnicodeUseLatestMapping;
status = CreateTextToUnicodeInfo(&theMapping, &textToUnicodeInfo);
if (status == noErr)
{
status = ConvertFromPStringToUnicode(textToUnicodeInfo, *machineName, maxlen, &unicodelen, (UniCharArrayPtr)&(utf8[1]));
DisposeTextToUnicodeInfo(&textToUnicodeInfo);
}
utf8[0] = (UInt8)unicodelen;
return(status);
}
mDNSlocal void GetUserSpecifiedComputerName(domainlabel *const namelabel)
{
StringHandle machineName = GetString(-16413); // Get machine name set in file sharing
if (machineName)
{
char machineNameState = HGetState((Handle)machineName);
HLock((Handle)machineName);
ConvertStringHandleToUTF8(machineName, namelabel->c, MAX_DOMAIN_LABEL);
HSetState((Handle)machineName, machineNameState);
}
}
#endif
static pascal void mDNSTimerTask(void *arg)
{
#if MDNS_ONLYSYSTEMTASK
#pragma unused(arg)
ONLYSYSTEMTASKevent = true;
#else
mDNS *const m = (mDNS *const)arg;
if (!m->p->ep) LogMsg("mDNSTimerTask NO endpoint");
if (m->mDNS_busy) LogMsg("mDNS_busy");
if (m->p->nesting) LogMsg("mDNSTimerTask ERROR! OTEnterNotifier is supposed to suppress timer callbacks too");
// If our timer fires at a time when we have no endpoint, ignore it --
// once we reopen our endpoint and get our T_BINDCOMPLETE message we'll call
// mDNS_RegisterInterface(), which does a lock/unlock, which retriggers the timer.
// Likewise, if m->mDNS_busy or m->p->nesting, we'll catch this on the unlock
if (m->p->ep && m->mDNS_busy == 0 && m->p->nesting == 0) mDNS_Execute(m);
#endif
}
#if TEST_SLEEP
long sleep, wake, mode;
#endif
mDNSexport mStatus mDNSPlatformInit (mDNS *const m)
{
OSStatus err = InitOpenTransport();
ClientNotifierContext = m;
// Note: OTRegisterAsClient returns kOTNotSupportedErr when running as Carbon code on OS X
// -- but that's okay, we don't need a ClientNotifier when running as Carbon code on OS X
OTRegisterAsClient(NULL, NewOTNotifyUPP(ClientNotifier));
m->p->OTTimerTask = OTCreateTimerTask(NewOTProcessUPP(mDNSTimerTask), m);
m->p->nesting = 0;
#if TEST_SLEEP
sleep = TickCount() + 600;
wake = TickCount() + 1200;
mode = 0;
#endif
// Set up the nice label
m->nicelabel.c[0] = 0;
GetUserSpecifiedComputerName(&m->nicelabel);
// m->nicelabel = *(domainlabel*)"\pStu"; // For conflict testing
if (m->nicelabel.c[0] == 0) MakeDomainLabelFromLiteralString(&m->nicelabel, "Macintosh");
// Set up the RFC 1034-compliant label
m->hostlabel.c[0] = 0;
ConvertUTF8PstringToRFC1034HostLabel(m->nicelabel.c, &m->hostlabel);
if (m->hostlabel.c[0] == 0) MakeDomainLabelFromLiteralString(&m->hostlabel, "Macintosh");
mDNS_SetFQDN(m);
// When it's finished mDNSOpenEndpoint asynchronously calls mDNSinitComplete() and then mDNS_RegisterInterface()
CallmDNSNotifierUPP = NewOTNotifyUPP(CallmDNSNotifier);
err = mDNSOpenEndpoint(m);
if (err)
{
LogMsg("mDNSOpenEndpoint failed %d", err);
if (m->p->OTTimerTask) OTDestroyTimerTask(m->p->OTTimerTask);
OTUnregisterAsClient();
CloseOpenTransport();
}
return(err);
}
extern void mDNSPlatformClose (mDNS *const m)
{
if (m->p->mOTstate == mOT_Ready)
{
m->p->mOTstate = mOT_Closed;
mDNS_DeregisterInterface(m, &m->p->interface, mDNSfalse);
}
if (m->p->ep) { OTCloseProvider (m->p->ep); m->p->ep = NULL; }
if (m->p->OTTimerTask) { OTDestroyTimerTask(m->p->OTTimerTask); m->p->OTTimerTask = 0; }
OTUnregisterAsClient();
CloseOpenTransport();
}
#if MDNS_ONLYSYSTEMTASK
extern void mDNSPlatformIdle(mDNS *const m);
mDNSexport void mDNSPlatformIdle(mDNS *const m)
{
while (ONLYSYSTEMTASKcontextPtr)
{
void *contextPtr = ONLYSYSTEMTASKcontextPtr;
ONLYSYSTEMTASKcontextPtr = NULL;
mDNSNotifier(contextPtr, ONLYSYSTEMTASKcode, ONLYSYSTEMTASKresult, ONLYSYSTEMTASKcookie);
}
if (ONLYSYSTEMTASKevent)
{
ONLYSYSTEMTASKevent = false;
mDNS_Execute(m);
}
if (m->p->mOTstate == mOT_Reset)
{
printf("\n");
printf("******************************************************************************\n");
printf("\n");
printf("Reopening endpoint\n");
mDNSOpenEndpoint(m);
m->ResourceRecords = NULL;
}
#if TEST_SLEEP
switch (mode)
{
case 0: if ((long)TickCount() - sleep >= 0) { mDNSCoreMachineSleep(m, 1); mode++; }
break;
case 1: if ((long)TickCount() - wake >= 0) { mDNSCoreMachineSleep(m, 0); mode++; }
break;
}
#endif
}
#endif
mDNSexport void mDNSPlatformLock(const mDNS *const m)
{
if (!m) { DebugStr("\pmDNSPlatformLock m NULL!"); return; }
if (!m->p) { DebugStr("\pmDNSPlatformLock m->p NULL!"); return; }
// If we try to call OTEnterNotifier and fail because we're already running at
// Notifier context, then make sure we don't do the matching OTLeaveNotifier() on exit.
// If we haven't even opened our endpoint yet, then just increment m->p->nesting for the same reason
if (m->p->mOTstate == mOT_Ready && !m->p->ep) DebugStr("\pmDNSPlatformLock: m->p->mOTstate == mOT_Ready && !m->p->ep");
if (!m->p->ep || m->p->nesting || OTEnterNotifier(m->p->ep) == false) m->p->nesting++;
}
mDNSlocal void ScheduleNextTimerCallback(const mDNS *const m)
{
if (m->mDNSPlatformStatus == mStatus_NoError)
{
SInt32 interval = m->NextScheduledEvent - mDNS_TimeNow_NoLock(m);
if (interval < 1) interval = 1;
else if (interval > 0x70000000 / 1000) interval = 0x70000000 / mDNSPlatformOneSecond;
else interval = (interval * 1000 + mDNSPlatformOneSecond-1)/ mDNSPlatformOneSecond;
OTScheduleTimerTask(m->p->OTTimerTask, (OTTimeout)interval);
}
}
mDNSexport void mDNSPlatformUnlock(const mDNS *const m)
{
if (!m) { DebugStr("\pmDNSPlatformUnlock m NULL!"); return; }
if (!m->p) { DebugStr("\pmDNSPlatformUnlock m->p NULL!"); return; }
if (m->p->ep && m->mDNS_busy == 0) ScheduleNextTimerCallback(m);
if (m->p->nesting) m->p->nesting--;
else OTLeaveNotifier(m->p->ep);
}
mDNSexport void mDNSPlatformStrCopy( void *dst, const void *src) { OTStrCopy((char*)dst, (char*)src); }
mDNSexport UInt32 mDNSPlatformStrLen ( const void *src) { return(OTStrLength((char*)src)); }
mDNSexport void mDNSPlatformMemCopy( void *dst, const void *src, UInt32 len) { OTMemcpy(dst, src, len); }
mDNSexport mDNSBool mDNSPlatformMemSame(const void *dst, const void *src, UInt32 len) { return(OTMemcmp(dst, src, len)); }
mDNSexport void mDNSPlatformMemZero( void *dst, UInt32 len) { OTMemzero(dst, len); }
mDNSexport void * mDNSPlatformMemAllocate(mDNSu32 len) { return(OTAllocMem(len)); }
mDNSexport void mDNSPlatformMemFree(void *mem) { OTFreeMem(mem); }
mDNSexport mDNSu32 mDNSPlatformRandomSeed(void) { return(TickCount()); }
mDNSexport mStatus mDNSPlatformTimeInit(void) { return(mStatus_NoError); }
mDNSexport SInt32 mDNSPlatformRawTime() { return((SInt32)TickCount()); }
mDNSexport SInt32 mDNSPlatformOneSecond = 60;
mDNSexport mDNSs32 mDNSPlatformUTC(void)
{
// Classic Mac OS since Midnight, 1st Jan 1904
// Standard Unix counts from 1970
// This value adjusts for the 66 years and 17 leap-days difference
mDNSu32 SecsSince1904;
MachineLocation ThisLocation;
#define TIME_ADJUST (((1970 - 1904) * 365 + 17) * 24 * 60 * 60)
#define ThisLocationGMTdelta ((ThisLocation.u.gmtDelta << 8) >> 8)
GetDateTime(&SecsSince1904);
ReadLocation(&ThisLocation);
return((mDNSs32)(SecsSince1904 - ThisLocationGMTdelta - TIME_ADJUST));
}

View File

@ -1,58 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// ***************************************************************************
// Classic Mac (Open Transport) structures
//#include <Files.h> // OpenTransport.h requires this
#include <OpenTransport.h>
#include <OpenTptInternet.h>
#include <OpenTptClient.h>
typedef enum
{
mOT_Closed = 0, // We got kOTProviderIsClosed message
mOT_Reset, // We got xOTStackWasLoaded message
mOT_Start, // We've called OTAsyncOpenEndpoint
mOT_ReusePort, // Have just done kReusePortOption
mOT_RcvDestAddr, // Have just done kRcvDestAddrOption
mOT_SetUTTL, // Have just done kSetUnicastTTLOption
mOT_SetMTTL, // Have just done kSetMulticastTTLOption
mOT_LLScope, // Have just done kAddLinkMulticastOption
// mOT_AdminScope, // Have just done kAddAdminMulticastOption
mOT_Bind, // We've just called OTBind
mOT_Ready // Got T_BINDCOMPLETE; Interface is registered and active
} mOT_State;
typedef struct { TOptionHeader h; mDNSv4Addr multicastGroupAddress; mDNSv4Addr InterfaceAddress; } TIPAddMulticastOption;
typedef struct { TOptionHeader h; UInt8 val; } TSetByteOption;
typedef struct { TOptionHeader h; UInt32 flag; } TSetBooleanOption;
// TOptionBlock is a union of various types.
// What they all have in common is that they all start with a TOptionHeader.
typedef union { TOptionHeader h; TIPAddMulticastOption m; TSetByteOption i; TSetBooleanOption b; } TOptionBlock;
struct mDNS_PlatformSupport_struct
{
EndpointRef ep;
UInt32 mOTstate; // mOT_State enum
TOptionBlock optBlock;
TOptMgmt optReq;
long OTTimerTask;
UInt32 nesting;
NetworkInterfaceInfo interface;
};

View File

@ -1,64 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Global definitions that apply to all source files
//
// Symbols that are defined here are available within all source files.
// This is the equivalent of using using "-d SYMBOL=VALUE" in a Makefile
// in command-line build environments.
// For normal DeferredTask time execution, set MDNS_ONLYSYSTEMTASK to 0
// For easier debugging, set MDNS_ONLYSYSTEMTASK to 1, and OT Notifier executions
// will be deferred until SystemTask time. (This option is available only for building
// the standalone application samples that have their own event loop -- don't try
// to build the System Extension with MDNS_ONLYSYSTEMTASK set because it won't work.)
#if __ide_target("Standalone TestResponder") || __ide_target("Standalone TestSearcher") || __ide_target("Standalone SubTypeTester")
#define TARGET_API_MAC_CARBON 1
#define OTCARBONAPPLICATION 1
#define MDNS_ONLYSYSTEMTASK 0
#define MDNS_DEBUGMSGS 0
#elif __ide_target("Standalone TestResponder (Debug)") || __ide_target("Standalone TestSearcher (Debug)")
#define TARGET_API_MAC_CARBON 1
#define OTCARBONAPPLICATION 1
#define MDNS_ONLYSYSTEMTASK 1
#define MDNS_DEBUGMSGS 1
#elif __ide_target("Standalone TestResponder (Classic)") || __ide_target("Standalone TestSearcher (Classic)")
#define MDNS_ONLYSYSTEMTASK 0
#define MDNS_DEBUGMSGS 0
#elif __ide_target("CFM Library for Extensions Folder")
#define MDNS_BUILDINGSHAREDLIBRARY 2
#elif __ide_target("CFM Library for Extensions (Debug)")
#define MDNS_DEBUGMSGS 0
#define MDNS_BUILDINGSHAREDLIBRARY 1
#elif __ide_target("CFM Stub for clients to link against")
#define MDNS_BUILDINGSTUBLIBRARY 1
#else
#error Options for this target not found in prefix file
#endif
// dnssd_clientlib.c assumes malloc() and free(), so we #define them here to be the OT equivalents
#if MDNS_BUILDINGSHAREDLIBRARY || MDNS_BUILDINGSTUBLIBRARY
#define malloc(x) OTAllocMem(x)
#define free(x) OTFreeMem(x)
#endif

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2010 Apple Inc. All rights reserved.
* Copyright (c) 2010-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -291,7 +291,8 @@ void * UserEventAgentFactory(CFAllocatorRef allocator, CFUUIDRef typeID)
(void)allocator;
BonjourUserEventsPlugin * result = NULL;
if (typeID && CFEqual(typeID, kUserEventAgentTypeID)) {
if (typeID && CFEqual(typeID, kUserEventAgentTypeID))
{
result = Alloc(kUserEventAgentFactoryID);
}
@ -604,8 +605,6 @@ NetBrowserInfo* CreateBrowser(BonjourUserEventsPlugin* plugin, CFStringRef type,
// Add the dictionary to the browsers dictionary.
CFDictionarySetValue(plugin->_browsers, browser, browserDict);
NetBrowserInfoRelease(NULL, browser);
// Release Memory
CFRelease(browserDict);
}

View File

@ -1,95 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2013 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mDNSMacOSX.h"
#include <network/config.h>
#if TARGET_OS_IPHONE
mDNSexport void CUPInit(mDNS *const m)
{
m->p->handle = cellular_usage_policy_create_client();
if (!m->p->handle)
{
LogMsg("CUPInit: cellular_usage_policy_create_client failed");
}
}
mDNSexport mDNSBool mDNSPlatformAllowPID(mDNS *const m, DNSQuestion *q)
{
// Currently the policy applies only for DNS requests sent over cellular interface
if (m->p->handle && q->qDNSServer && q->qDNSServer->cellIntf)
{
mDNSBool allowed;
if (q->pid)
{
allowed = (mDNSBool) cellular_usage_policy_is_data_allowed_for_pid(m->p->handle, q->pid);
if (!allowed)
{
xpc_object_t pidx = xpc_uint64_create(q->pid);
if (pidx)
{
network_config_cellular_blocked_notify(pidx, NULL, NULL);
LogInfo("mDNSPlaformAllowPID: Notified PID(%d) for %##s (%s)", q->pid, q->qname.c, DNSTypeName(q->qtype));
xpc_release(pidx);
}
}
}
else
{
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
{
return mDNStrue;
}
}
#else // TARGET_OS_IPHONE
mDNSexport void CUPInit(mDNS *const m)
{
(void)m; //unused
}
mDNSexport mDNSBool mDNSPlatformAllowPID(mDNS *const m, DNSQuestion *q)
{
(void)m; //unused
(void)q; //unused
//LogMsg("mDNSPlatformAllowPID: %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
return mDNStrue;
}
#endif // TARGET_OS_IPHONE

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -350,18 +350,18 @@ mDNSlocal mStatus rsa_sha_add(AlgContext *ctx, const void *data, mDNSu32 len)
mDNSlocal SecKeyRef rfc3110_import(const mDNSu8 *data, const mDNSu32 len)
{
static const int max_key_bytes = 4096 / 8; // max DNSSEC supported modulus is 4096 bits
static const int max_exp_bytes = 3; // DNSSEC supports 1 or 3 bytes for exponent
static const int asn1_cmd_bytes = 3; // since there is an ASN1 SEQ and two INTs
//static const int asn1_max_len_bytes = asn1_cmd_bytes * 3; // capped at 3 due to max payload size
static const int asn1_max_len_bytes = 3 * 3; // capped at 3 due to max payload size
unsigned char asn1[max_key_bytes + 1 + max_exp_bytes + asn1_cmd_bytes + asn1_max_len_bytes]; // +1 is for leading 0 for non negative asn1 number
static const int max_modulus_bytes = 512; // Modulus is limited to 4096 bits (512 octets) in length.
static const int max_exp_bytes = 512; // Exponent is limited to 4096 bits (512 octets) in length.
static const int asn1_type_bytes = 3; // Since there is an ASN1 SEQ and two INTs.
static const int asn1_max_len_bytes = 3 * 3; // Capped at 3 due to max payload size.
unsigned char asn1[max_modulus_bytes + 1 + max_exp_bytes + asn1_type_bytes + asn1_max_len_bytes]; // +1 is for leading 0 for non negative asn1 number
const mDNSu8 *modulus;
unsigned int modulus_length;
const mDNSu8 *exponent;
unsigned int exp_length;
unsigned int num_length_bytes;
mDNSu32 index = 0;
mDNSu32 asn1_length = 0;
unsigned int i;
// Validate Input
if (!data)
@ -372,16 +372,33 @@ mDNSlocal SecKeyRef rfc3110_import(const mDNSu8 *data, const mDNSu32 len)
return NULL;
// Parse Modulus and Exponent
exp_length = data[0];
// we have to have at least len byte + size of exponent
if (len < 1+exp_length)
// If the first byte is zero, then the exponent length is in the three-byte format, otherwise the length is in the first byte.
if (data[0] == 0)
{
if (len < 3)
return NULL;
exp_length = (data[1] << 8) | data[2];
num_length_bytes = 3;
}
else
{
exp_length = data[0];
num_length_bytes = 1;
}
// RFC3110 limits the exponent length to 4096 bits (512 octets).
if (exp_length > 512)
return NULL;
// -1 is for the exp_length byte
modulus_length = len - 1 - exp_length;
// We have to have at least len bytes + size of exponent.
if (len < (num_length_bytes + exp_length))
return NULL;
// rfc3110 limits modulus to 4096 bits
// The modulus is the remaining space.
modulus_length = len - (num_length_bytes + exp_length);
// RFC3110 limits the modulus length to 4096 bits (512 octets).
if (modulus_length > 512)
return NULL;
@ -391,18 +408,30 @@ mDNSlocal SecKeyRef rfc3110_import(const mDNSu8 *data, const mDNSu32 len)
// add 1 to modulus length for pre-ceding 0 t make ASN1 value non-negative
++modulus_length;
// 1 is to skip exp_length byte
modulus = &data[1+exp_length];
exponent = &data[num_length_bytes];
modulus = &data[num_length_bytes + exp_length];
// 2 bytes for commands since first doesn't count
// 2 bytes for min 1 byte length field
asn1_length = modulus_length + exp_length + 2 + 2;
// account for modulus length causing INT length field to grow
if (modulus_length > 0xFF)
// Account for modulus length causing INT length field to grow.
if (modulus_length >= 128)
{
if (modulus_length > 255)
asn1_length += 2;
else if (modulus_length >= 128)
++asn1_length;
else
asn1_length += 1;
}
// Account for exponent length causing INT length field to grow.
if (exp_length >= 128)
{
if (exp_length > 255)
asn1_length += 2;
else
asn1_length += 1;
}
// Construct ASN1 formatted public key
// Write ASN1 SEQ byte
@ -415,8 +444,8 @@ mDNSlocal SecKeyRef rfc3110_import(const mDNSu8 *data, const mDNSu32 len)
}
else
{
asn1[index++] = (0x80 | ((asn1_length & 0xFF00) ? 2 : 1));
if (asn1_length & 0xFF00)
asn1[index++] = (0x80 | ((asn1_length > 255) ? 2 : 1));
if (asn1_length > 255)
asn1[index++] = (asn1_length & 0xFF00) >> 8;
asn1[index++] = asn1_length & 0xFF;
}
@ -426,12 +455,12 @@ mDNSlocal SecKeyRef rfc3110_import(const mDNSu8 *data, const mDNSu32 len)
// Write ASN1 length for INT
if (modulus_length < 128)
{
asn1[index++] = asn1_length & 0xFF;
asn1[index++] = modulus_length & 0xFF;
}
else
{
asn1[index++] = 0x80 | ((modulus_length & 0xFF00) ? 2 : 1);
if (modulus_length & 0xFF00)
asn1[index++] = 0x80 | ((modulus_length > 255) ? 2 : 1);
if (modulus_length > 255)
asn1[index++] = (modulus_length & 0xFF00) >> 8;
asn1[index++] = modulus_length & 0xFF;
}
@ -439,16 +468,26 @@ mDNSlocal SecKeyRef rfc3110_import(const mDNSu8 *data, const mDNSu32 len)
// Write preceding 0 so our integer isn't negative
asn1[index++] = 0x00;
// Write actual modulus (-1 for preceding 0)
memcpy(&asn1[index], (void *)modulus, modulus_length-1);
index += modulus_length-1;
memcpy(&asn1[index], modulus, modulus_length - 1);
index += (modulus_length - 1);
// Write ASN1 INT for exponent
asn1[index++] = 0x02;
// Write ASN1 length for INT
if (exp_length < 128)
{
asn1[index++] = exp_length & 0xFF;
}
else
{
asn1[index++] = 0x80 | ((exp_length > 255) ? 2 : 1);
if (exp_length > 255)
asn1[index++] = (exp_length & 0xFF00) >> 8;
asn1[index++] = exp_length & 0xFF;
}
// Write exponent bytes
for (i = 1; i <= exp_length; i++)
asn1[index++] = data[i];
memcpy(&asn1[index], exponent, exp_length);
index += exp_length;
#if TARGET_OS_IPHONE
// index contains bytes written, use it for length
@ -605,6 +644,8 @@ mDNSlocal Boolean VerifyData(SecKeyRef key, CFStringRef digestStr, mDNSu8 *diges
}
CFBooleanRef boolRef = SecTransformExecute(verifyXForm, &error);
ret = boolRef ? CFBooleanGetValue(boolRef) : false;
if (boolRef) CFRelease(boolRef);
CFRelease(verifyXForm);
if (error != NULL)
@ -618,11 +659,12 @@ mDNSlocal Boolean VerifyData(SecKeyRef key, CFStringRef digestStr, mDNSu8 *diges
{
LogMsg("VerifyData: CFStringGetCString failed");
}
CFRelease(errStr);
}
LogMsg("VerifyData: SecTransformExecute failed with %s", errorbuf);
return false;
}
return CFEqual(boolRef, kCFBooleanTrue);
return ret;
err:
CFRelease(verifyXForm);
return false;

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CRYPTO_SUPPORT_H
#define __CRYPTO_SUPPORT_H

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2011-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mDNSEmbeddedAPI.h"
#include "mDNSMacOSX.h"
@ -261,11 +262,9 @@ mDNSlocal mStatus SetupUDPProxySocket(mDNS *const m, int skt, KQSocketSet *cp, u
int *s = (sa_family == AF_INET) ? &cp->sktv4 : &cp->sktv6;
KQueueEntry *k = (sa_family == AF_INET) ? &cp->kqsv4 : &cp->kqsv6;
const int on = 1;
mDNSIPPort port;
mStatus err = mStatus_NoError;
cp->m = m;
port = cp->port;
cp->closeFlag = mDNSNULL;
// set default traffic class
@ -339,11 +338,9 @@ mDNSlocal mStatus SetupTCPProxySocket(mDNS *const m, int skt, KQSocketSet *cp, u
{
int *s = (sa_family == AF_INET) ? &cp->sktv4 : &cp->sktv6;
KQueueEntry *k = (sa_family == AF_INET) ? &cp->kqsv4 : &cp->kqsv6;
mDNSIPPort port;
mStatus err;
cp->m = m;
port = cp->port;
// XXX may not be used by the TCP codepath
cp->closeFlag = mDNSNULL;
@ -384,7 +381,7 @@ mDNSlocal void BindDPSocket(int fd, int sa_family)
err = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
if (err < 0)
LogMsg("BindDPSocket: setsockopt SO_REUSEPORT failed for V4 %d errno %d (%s)", fd, errno, strerror(errno));
LogMsg("BindDPSocket: setsockopt SO_REUSEPORT failed for IPv4 %d errno %d (%s)", fd, errno, strerror(errno));
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2012-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -449,9 +449,13 @@ mDNSlocal void FetchRootTA(mDNS *const m)
return;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
// If we can't fetch the XML file e.g., network problems, trigger a timer. All other failures
// should hardly happen in practice for which schedule the normal interval to refetch the TA.
if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, url, &xmlData, NULL, NULL, NULL))
Boolean success = CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, url, &xmlData, NULL, NULL, NULL);
#pragma clang diagnostic pop
if (!success)
{
LogInfo("FetchRootTA: CFURLCreateDataAndPropertiesFromResource error");
CFRelease(url);
@ -479,6 +483,7 @@ mDNSlocal void FetchRootTA(mDNS *const m)
xmlDocPtr tadoc = xmlReadMemory((const char*)CFDataGetBytePtr(xmlData),
(int)CFDataGetLength(xmlData), xmlFileName, NULL, 0);
if (fileRef)
CFRelease(fileRef);
CFRelease(url);
CFRelease(xmlData);

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2012-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -453,7 +453,6 @@ DNSServiceRegistrationReplyErrorType DNSServiceRegistrationRemoveRecord(dns_serv
void DNSServiceDiscovery_handleReply(void *replyMsg)
{
unsigned long result = 0xFFFFFFFF;
mach_msg_header_t * msgSendBufPtr;
mach_msg_header_t * receivedMessage;
unsigned msgSendBufLength;
@ -466,7 +465,7 @@ void DNSServiceDiscovery_handleReply(void *replyMsg)
// Call DNSServiceDiscoveryReply_server to change mig-generated message into a
// genuine mach message. It will then cause the callback to get called.
result = DNSServiceDiscoveryReply_server ( receivedMessage, msgSendBufPtr );
DNSServiceDiscoveryReply_server ( receivedMessage, msgSendBufPtr );
( void ) mach_msg_send ( msgSendBufPtr );
free(msgSendBufPtr);
}

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002, 2004, 2006, 2011 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002-2003, 2006, 2009, 2011 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002-2003, 2006 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002-2004, 2006 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.mDNSResponderHelper</string>
<key>OnDemand</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/mDNSResponderHelper</string>
<string>-t</string>
<string>0</string>
</array>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.mDNSResponder</string>
<key>OnDemand</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/mDNSResponder</string>
<string>-launchdaemon</string>
</array>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2004-2013 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2004-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,6 +22,7 @@
#include "assert.h" // For assert()
#if defined( WIN32 )
# include "CommonServices.h"
# include <winsock2.h>
# include <ws2tcpip.h>
# define strcasecmp _stricmp
@ -82,8 +83,11 @@ mDNSlocal mStatus SendPortMapRequest(mDNS *m, NATTraversalInfo *n);
mDNSlocal void AllocAndCopy(mDNSu8 **const dst, const mDNSu8 *const src)
{
if (src == mDNSNULL) return;
if ((*dst = mDNSPlatformMemAllocate((mDNSu32)strlen((char*)src) + 1)) == mDNSNULL)
{ LogMsg("AllocAndCopy: can't allocate string"); return; }
if ((strlen((char*)src)) >= UINT32_MAX || (*dst = mDNSPlatformMemAllocate((mDNSu32)strlen((char*)src) + 1)) == mDNSNULL)
{
LogMsg("AllocAndCopy: can't allocate string");
return;
}
strcpy((char*)*dst, (char*)src);
}
@ -279,7 +283,7 @@ mDNSlocal void handleLNTDeviceDescriptionResponse(tcpLNTInfo *tcpInfo)
LogInfo("handleLNTDeviceDescriptionResponse: found URLBase");
ptr += 8; // skip over "URLBase>"
// find the end of the URLBase element
for (stop = ptr; stop < end; stop++) { if (*stop == '<') { end = stop; break; } }
for (stop = ptr; stop < end; stop++) { if (stop && *stop == '<') { end = stop; break; } }
if (ParseHttpUrl(ptr, end, &m->UPnPSOAPAddressString, &m->UPnPSOAPPort, mDNSNULL) != mStatus_NoError)
{
LogInfo("handleLNTDeviceDescriptionResponse: failed to parse URLBase");
@ -412,8 +416,6 @@ mDNSlocal void tcpConnectionCallback(TCPSocket *sock, void *context, mDNSBool Co
long nsent = 0;
static int LNTERRORcount = 0;
if (tcpInfo == mDNSNULL) { LogInfo("tcpConnectionCallback: no tcpInfo context"); status = mStatus_Invalid; goto exit; }
if (tcpInfo->sock != sock)
{
LogMsg("tcpConnectionCallback: WARNING- tcpInfo->sock(%p) != sock(%p) !!! Printing tcpInfo struct", tcpInfo->sock, sock);
@ -793,7 +795,7 @@ mDNSexport void LNT_ConfigureRouterInfo(mDNS *m, const mDNSInterfaceID Interface
{
const mDNSu8 *ptr = data;
const mDNSu8 *end = data + len;
const mDNSu8 *stop = ptr;
const mDNSu8 *stop;
if (!mDNSIPPortIsZero(m->UPnPRouterPort)) return; // already have the info we need

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2016 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -15,4 +15,23 @@
* limitations under the License.
*/
data 'carb' (0) { };
#include "mDNSEmbeddedAPI.h"
#ifndef __Metrics_h
#define __Metrics_h
#ifdef __cplusplus
extern "C" {
#endif
#if TARGET_OS_EMBEDDED
mStatus MetricsInit(void);
void MetricsUpdateUDNSStats(const domainname *inQueryName, mDNSBool inAnswered, mDNSu32 inSendCount, mDNSu32 inLatencyMs, mDNSBool inForCellular);
void LogMetrics(void);
#endif
#ifdef __cplusplus
}
#endif
#endif // __Metrics_h

View File

@ -0,0 +1,531 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2016 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "Metrics.h"
#if TARGET_OS_EMBEDDED
#import <CoreUtils/SoftLinking.h>
#import <WirelessDiagnostics/AWDDNSDomainStats.h>
#import <WirelessDiagnostics/AWDMDNSResponderDNSStatistics.h>
#import <WirelessDiagnostics/AWDMetricIds_MDNSResponder.h>
#import <WirelessDiagnostics/WirelessDiagnostics.h>
#import "DNSCommon.h"
#import "mDNSMacOSX.h"
#import "DebugServices.h"
//===========================================================================================================================
// External Frameworks
//===========================================================================================================================
SOFT_LINK_FRAMEWORK(PrivateFrameworks, WirelessDiagnostics)
SOFT_LINK_CLASS(WirelessDiagnostics, AWDServerConnection)
#define AWDServerConnectionSoft getAWDServerConnectionClass()
SOFT_LINK_CLASS(WirelessDiagnostics, AWDMDNSResponderDNSStatistics)
#define AWDMDNSResponderDNSStatisticsSoft getAWDMDNSResponderDNSStatisticsClass()
SOFT_LINK_CLASS(WirelessDiagnostics, AWDDNSDomainStats)
#define AWDDNSDomainStatsSoft getAWDDNSDomainStatsClass()
//===========================================================================================================================
// Macros
//===========================================================================================================================
#define countof(X) (sizeof(X) / sizeof(X[0]))
//===========================================================================================================================
// Constants
//===========================================================================================================================
#define kUDNSStatsMaxQuerySendCount 10
// Important: Do not update this list without getting privacy approval. See <rdar://problem/24155761>.
static const char * const kUDNSStatsDomains[] =
{
".",
"apple.com.",
"icloud.com.",
"me.com.",
"google.com.",
"facebook.com.",
"youtube.com.",
"baidu.com.",
"amazon.com.",
"yahoo.com.",
"wikipedia.org."
};
static const mDNSu32 kResponseLatencyMsLimits[] =
{
1, 2, 3, 4, 5,
10, 20, 30, 40, 50, 60, 70, 80, 90,
100, 110, 120, 130, 140, 150, 160, 170, 180, 190,
200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950,
1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500,
5000, 6000, 7000, 8000, 9000,
10000
};
//===========================================================================================================================
// Data structures
//===========================================================================================================================
typedef struct
{
uint32_t answeredQuerySendCountBins[kUDNSStatsMaxQuerySendCount + 1];
uint32_t unansweredQuerySendCountBins[kUDNSStatsMaxQuerySendCount + 1];
uint32_t responseLatencyBins[countof(kResponseLatencyMsLimits) + 1];
} DNSStats;
typedef struct DNSDomainStats * DNSDomainStatsRef;
struct DNSDomainStats
{
DNSDomainStatsRef next;
domainname domain;
int domainLabelCount;
char * domainStr;
DNSStats stats;
DNSStats statsCellular;
};
//===========================================================================================================================
// Globals
//===========================================================================================================================
extern mDNS mDNSStorage;
static DNSDomainStatsRef gDomainStatsList = NULL;
static AWDServerConnection * gAWDServerConnection = nil;
//===========================================================================================================================
// Local Prototypes
//===========================================================================================================================
mDNSlocal mStatus DNSDomainStatsCreate(const char *inDomain, DNSDomainStatsRef *outStats);
mDNSlocal void DNSDomainStatsFree(DNSDomainStatsRef inStats);
mDNSlocal void DNSDomainStatsFreeList(DNSDomainStatsRef inList);
mDNSlocal mStatus CreateDomainStatsList(DNSDomainStatsRef *outList);
mDNSlocal void UpdateDNSStats(DNSStats *inStats, mDNSBool inAnswered, mDNSu32 inQuerySendCount, mDNSu32 inLatencyMs);
mDNSlocal mStatus SubmitAWDMetric(void);
mDNSlocal mStatus CreateAWDDNSDomainStats(DNSStats *inStats, const char *inDomain, mDNSBool inIsForCellular, AWDDNSDomainStats **outAWDStats);
mDNSlocal void LogDNSStats(const DNSStats *inStats);
//===========================================================================================================================
// MetricsInit
//===========================================================================================================================
mStatus MetricsInit(void)
{
mStatus err;
err = CreateDomainStatsList(&gDomainStatsList);
require_noerr_quiet(err, exit);
@autoreleasepool
{
gAWDServerConnection = [[AWDServerConnectionSoft alloc]
initWithComponentId: AWDComponentId_MDNSResponder
andBlockOnConfiguration: NO];
if (gAWDServerConnection)
{
[gAWDServerConnection
registerQueriableMetricCallback: ^(UInt32 metricId)
{
mStatus localErr;
(void) metricId;
localErr = SubmitAWDMetric();
if (localErr) LogMsg("SubmitAWDMetric failed with error %d", localErr);
}
forIdentifier: (UInt32)AWDMetricId_MDNSResponder_DNSStatistics];
}
}
exit:
return (err);
}
//===========================================================================================================================
// MetricsUpdateUDNSStats
//===========================================================================================================================
mDNSexport void MetricsUpdateUDNSStats(const domainname *inQueryName, mDNSBool inAnswered, mDNSu32 inSendCount, mDNSu32 inLatencyMs, mDNSBool inForCellular)
{
DNSStats * stats;
DNSDomainStatsRef domainStats;
int queryLabelCount;
mDNSBool isQueryInDomain;
queryLabelCount = CountLabels(inQueryName);
for (domainStats = gDomainStatsList; domainStats; domainStats = domainStats->next)
{
isQueryInDomain = mDNSfalse;
if (strcmp(domainStats->domainStr, ".") == 0)
{
// All queries are in the root domain.
isQueryInDomain = mDNStrue;
}
else
{
int skipCount;
const domainname * queryParentDomain;
skipCount = queryLabelCount - domainStats->domainLabelCount;
if (skipCount >= 0)
{
queryParentDomain = SkipLeadingLabels(inQueryName, skipCount);
isQueryInDomain = SameDomainName(queryParentDomain, &domainStats->domain);
}
}
if (isQueryInDomain)
{
stats = inForCellular ? &domainStats->statsCellular : &domainStats->stats;
UpdateDNSStats(stats, inAnswered, inSendCount, inLatencyMs);
}
}
}
//===========================================================================================================================
// CreateDomainStatsList
//===========================================================================================================================
mDNSlocal mStatus CreateDomainStatsList(DNSDomainStatsRef *outList)
{
mStatus err;
size_t i;
DNSDomainStatsRef domainStats;
DNSDomainStatsRef * p;
DNSDomainStatsRef list = NULL;
p = &list;
for (i = 0; i < countof(kUDNSStatsDomains); ++i)
{
err = DNSDomainStatsCreate(kUDNSStatsDomains[i], &domainStats);
require_noerr_quiet(err, exit);
*p = domainStats;
p = &domainStats->next;
}
*outList = list;
list = NULL;
exit:
DNSDomainStatsFreeList(list);
return (err);
}
//===========================================================================================================================
// UpdateDNSStats
//===========================================================================================================================
mDNSlocal void UpdateDNSStats(DNSStats *inStats, mDNSBool inAnswered, mDNSu32 inQuerySendCount, mDNSu32 inLatencyMs)
{
size_t i;
if (inAnswered)
{
i = (inQuerySendCount <= kUDNSStatsMaxQuerySendCount) ? inQuerySendCount : kUDNSStatsMaxQuerySendCount;
inStats->answeredQuerySendCountBins[i]++;
if (inQuerySendCount > 0)
{
for (i = 0; (i < countof(kResponseLatencyMsLimits)) && (inLatencyMs >= kResponseLatencyMsLimits[i]); ++i) {}
inStats->responseLatencyBins[i]++;
}
}
else if (inQuerySendCount > 0)
{
i = (inQuerySendCount <= kUDNSStatsMaxQuerySendCount) ? inQuerySendCount : kUDNSStatsMaxQuerySendCount;
inStats->unansweredQuerySendCountBins[i]++;
}
}
//===========================================================================================================================
// SubmitAWDMetric
//===========================================================================================================================
mDNSlocal mStatus SubmitAWDMetric(void)
{
mStatus err;
BOOL success;
DNSDomainStatsRef domainStats;
DNSDomainStatsRef newDomainStatsList;
DNSDomainStatsRef domainStatsList = NULL;
AWDMetricContainer * container = nil;
AWDMDNSResponderDNSStatistics * metric = nil;
AWDDNSDomainStats * awdDomainStats = nil;
err = CreateDomainStatsList(&newDomainStatsList);
require_noerr_quiet(err, exit);
domainStatsList = gDomainStatsList;
KQueueLock(&mDNSStorage);
gDomainStatsList = newDomainStatsList;
KQueueUnlock(&mDNSStorage, "SubmitAWDMetric");
container = [gAWDServerConnection newMetricContainerWithIdentifier:AWDMetricId_MDNSResponder_DNSStatistics];
require_action_quiet(container, exit, err = mStatus_UnknownErr);
metric = [[AWDMDNSResponderDNSStatisticsSoft alloc] init];
require_action_quiet(metric, exit, err = mStatus_UnknownErr);
for (domainStats = domainStatsList; domainStats; domainStats = domainStats->next)
{
err = CreateAWDDNSDomainStats(&domainStats->stats, domainStats->domainStr, mDNSfalse, &awdDomainStats);
require_noerr_quiet(err, exit);
[metric addStats:awdDomainStats];
[awdDomainStats release];
awdDomainStats = nil;
err = CreateAWDDNSDomainStats(&domainStats->statsCellular, domainStats->domainStr, mDNStrue, &awdDomainStats);
require_noerr_quiet(err, exit);
[metric addStats:awdDomainStats];
[awdDomainStats release];
awdDomainStats = nil;
}
container.metric = metric;
success = [gAWDServerConnection submitMetric:container];
LogMsg("SubmitAWDMetric: metric submission %s.", success ? "succeeded" : "failed" );
err = success ? mStatus_NoError : mStatus_UnknownErr;
exit:
[awdDomainStats release];
[metric release];
[container release];
DNSDomainStatsFreeList(domainStatsList);
return (err);
}
//===========================================================================================================================
// DNSDomainStatsCreate
//===========================================================================================================================
mDNSlocal mStatus DNSDomainStatsCreate(const char *inDomain, DNSDomainStatsRef *outStats)
{
mStatus err;
DNSDomainStatsRef obj;
mDNSu8 * ptr;
obj = (DNSDomainStatsRef) calloc(1, sizeof(*obj));
require_action_quiet(obj, exit, err = mStatus_NoMemoryErr);
obj->domainStr = strdup(inDomain);
require_action_quiet(obj, exit, err = mStatus_NoMemoryErr);
// Initialize domainname for non-root domains.
if (strcmp(obj->domainStr, ".") != 0)
{
ptr = MakeDomainNameFromDNSNameString(&obj->domain, obj->domainStr);
require_action_quiet(ptr, exit, err = mStatus_Invalid);
obj->domainLabelCount = CountLabels(&obj->domain);
}
*outStats = obj;
obj = NULL;
err = mStatus_NoError;
exit:
if (obj) DNSDomainStatsFree(obj);
return (err);
}
//===========================================================================================================================
// DNSDomainStatsFree
//===========================================================================================================================
mDNSlocal void DNSDomainStatsFree(DNSDomainStatsRef inStats)
{
if (inStats->domainStr) free(inStats->domainStr);
free(inStats);
}
//===========================================================================================================================
// DNSDomainStatsFreeList
//===========================================================================================================================
mDNSlocal void DNSDomainStatsFreeList(DNSDomainStatsRef inList)
{
DNSDomainStatsRef stats;
while ((stats = inList) != NULL)
{
inList = stats->next;
DNSDomainStatsFree(stats);
}
}
//===========================================================================================================================
// CreateAWDDNSDomainStats
//===========================================================================================================================
mDNSlocal mStatus CreateAWDDNSDomainStats(DNSStats *inStats, const char *inDomain, mDNSBool inIsCellType, AWDDNSDomainStats **outAWDStats)
{
mStatus err;
AWDDNSDomainStats * awdStats = nil;
NSString * domain = nil;
awdStats = [[AWDDNSDomainStatsSoft alloc] init];
require_action_quiet(awdStats, exit, err = mStatus_UnknownErr);
domain = [[NSString alloc] initWithUTF8String:inDomain];
require_action_quiet(domain, exit, err = mStatus_UnknownErr);
awdStats.domain = domain;
awdStats.networkType = inIsCellType ? AWDDNSDomainStats_NetworkType_Cellular : AWDDNSDomainStats_NetworkType_NonCellular;
[awdStats
setAnsweredQuerySendCounts: inStats->answeredQuerySendCountBins
count: (NSUInteger)countof(inStats->answeredQuerySendCountBins)];
[awdStats
setUnansweredQuerySendCounts: inStats->unansweredQuerySendCountBins
count: (NSUInteger)countof(inStats->unansweredQuerySendCountBins)];
[awdStats
setResponseLatencyMs: inStats->responseLatencyBins
count: (NSUInteger)countof(inStats->responseLatencyBins)];
*outAWDStats = awdStats;
awdStats = nil;
err = mStatus_NoError;
exit:
[domain release];
[awdStats release];
return (err);
}
//===========================================================================================================================
// LogDNSStats
//===========================================================================================================================
#define Percent(N, D) ((N) * 100) / (D), (((N) * 10000) / (D)) % 100
#define PercentFmt "%3u.%02u"
#define LogStat(LABEL, COUNT, ACCUMULATOR, TOTAL) \
LogMsgNoIdent("%s %5u " PercentFmt " " PercentFmt, (LABEL), (COUNT), Percent(COUNT, TOTAL), Percent(ACCUMULATOR, TOTAL))
mDNSlocal void LogDNSStats(const DNSStats *inStats)
{
uint32_t total;
uint32_t totalUnanswered;
size_t i;
char label[16];
totalUnanswered = 0;
for (i = 0; i < countof(inStats->unansweredQuerySendCountBins); ++i)
{
totalUnanswered += inStats->unansweredQuerySendCountBins[i];
}
total = 0;
for (i = 0; i <= countof(inStats->answeredQuerySendCountBins); ++i)
{
total += inStats->answeredQuerySendCountBins[i];
}
LogMsgNoIdent("Answered questions %5u", total);
LogMsgNoIdent("Unanswered questions %5u", totalUnanswered);
LogMsgNoIdent("+++ Number of queries sent +++");
if (total > 0)
{
uint32_t accumulator = 0;
for (i = 0; i < countof(inStats->answeredQuerySendCountBins); ++i)
{
uint32_t count;
const char * suffix;
count = inStats->answeredQuerySendCountBins[i];
accumulator += count;
suffix = (i < (countof(inStats->answeredQuerySendCountBins) - 1)) ? " " : "+";
snprintf(label, sizeof(label), "%2d%s", (int)i, suffix);
LogStat(label, count, accumulator, total);
}
}
else
{
LogMsgNoIdent("No data.");
}
total = 0;
for (i = 0; i < countof(inStats->responseLatencyBins); ++i)
{
total += inStats->responseLatencyBins[i];
}
LogMsgNoIdent("+++++++ Response times +++++++");
if (total > 0)
{
uint32_t accumulator = 0;
for (i = 0; i < countof(inStats->responseLatencyBins); ++i)
{
uint32_t count;
count = inStats->responseLatencyBins[i];
accumulator += count;
if (i < countof(kResponseLatencyMsLimits))
{
snprintf(label, sizeof(label), "< %5u ms", kResponseLatencyMsLimits[i]);
}
else
{
snprintf(label, sizeof(label), "< ∞ ms");
}
LogStat(label, count, accumulator, total);
if (accumulator == total) break;
}
}
else
{
LogMsgNoIdent("No data.");
}
}
//===========================================================================================================================
// LogMetrics
//===========================================================================================================================
mDNSexport void LogMetrics(void)
{
DNSDomainStatsRef domainStats;
LogMsgNoIdent("---- DNS stats by domain -----");
for (domainStats = gDomainStatsList; domainStats; domainStats = domainStats->next)
{
LogMsgNoIdent("Domain: %s (non-cellular)", domainStats->domainStr);
LogDNSStats(&domainStats->stats);
LogMsgNoIdent("Domain: %s (cellular)", domainStats->domainStr);
LogDNSStats(&domainStats->statsCellular);
}
}
#endif // TARGET_OS_EMBEDDED

View File

@ -1,4 +1,4 @@
/*
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
@ -250,7 +250,8 @@ int P2PPacketFilterAddBonjourRuleSet(const char * interfaceName, u_int32_t count
require( result == 0, exit );
// open inbound port for each service
for (i = 0; i < count; i++) {
for (i = 0; i < count; i++)
{
initPortRule( &pr, interfaceName, ticket, poolTicket, anchorPath, portArray[i], protocolArray[i] );
result = addRule( devFD, &pr );
require( result == 0, exit );

View File

@ -1,4 +1,4 @@
/*
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*

View File

@ -3,9 +3,9 @@
Abstract: System Preference Pane for Dynamic DNS and Wide-Area DNS Service Discovery
Copyright: (c) Copyright 2005-2011 Apple Computer, Inc. All rights reserved.
Copyright: (c) Copyright 2005-2011 Apple Inc. All rights reserved.
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
@ -19,7 +19,7 @@
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
@ -96,7 +96,6 @@ static void ServiceDomainEnumReply( DNSServiceRef sdRef, DNSServiceFlags flags,
NSMutableArray * defaultBrowseDomainsArray = nil;
NSComboBox * domainComboBox;
NSString * domainString;
NSString * currentDomain = nil;
char decodedDomainString[kDNSServiceMaxDomainName] = "\0";
char nextLabel[256] = "\0";
char * buffer = (char *)replyDomain;
@ -115,7 +114,6 @@ static void ServiceDomainEnumReply( DNSServiceRef sdRef, DNSServiceFlags flags,
if (enumType & kDNSServiceFlagsRegistrationDomains) {
domainArray = [me registrationDataSource];
domainComboBox = [me regDomainsComboBox];
currentDomain = [me currentRegDomain];
} else {
domainArray = [me browseDataSource];
domainComboBox = [me browseDomainsComboBox];
@ -261,6 +259,7 @@ MyDNSServiceAddServiceToRunLoop(MyDNSServiceState * query)
assert(rls != NULL);
CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopCommonModes);
CFRelease(rls);
CFRelease(keys);
CFRelease(store);
@ -334,7 +333,7 @@ MyDNSServiceAddServiceToRunLoop(MyDNSServiceState * query)
currentHostName = [[NSString alloc] initWithString:@""];
}
[origDict release];
CFRelease((CFDictionaryRef)origDict);
CFRelease(store);
}
@ -394,6 +393,7 @@ MyDNSServiceAddServiceToRunLoop(MyDNSServiceState * query)
[browseDomainsArray replaceObjectAtIndex:[tableView clickedRow] withObject:browseDomainDict];
[tableView reloadData];
[self updateApplyButtonState];
[browseDomainDict release];
}
@ -681,12 +681,8 @@ MyDNSServiceAddServiceToRunLoop(MyDNSServiceState * query)
{
NSString *hostNameString = [hostName stringValue];
NSString *regDomainString = [regDomainsComboBox stringValue];
NSComparisonResult hostNameResult = [hostNameString compare:currentHostName];
NSComparisonResult regDomainResult = [regDomainString compare:currentRegDomain];
if ((currentHostName && (hostNameResult != NSOrderedSame)) ||
(currentRegDomain && (regDomainResult != NSOrderedSame) && ([wideAreaCheckBox state])) ||
if ((currentHostName && ([hostNameString compare:currentHostName] != NSOrderedSame)) ||
(currentRegDomain && ([regDomainString compare:currentRegDomain] != NSOrderedSame) && ([wideAreaCheckBox state])) ||
(currentHostName == nil && ([hostNameString length]) > 0) ||
(currentRegDomain == nil && ([regDomainString length]) > 0) ||
(currentWideAreaState != [wideAreaCheckBox state]) ||
@ -946,7 +942,7 @@ MyDNSServiceAddServiceToRunLoop(MyDNSServiceState * query)
}
CFRelease(itemRef);
}
return keyName;
return [keyName autorelease];
}
@ -1000,7 +996,6 @@ MyDNSServiceAddServiceToRunLoop(MyDNSServiceState * query)
-(void)savePreferences
{
NSString *hostNameString = [hostName stringValue];
NSString *browseDomainString = [browseDomainsComboBox stringValue];
NSString *regDomainString = [regDomainsComboBox stringValue];
NSString *tempHostNameSharedSecretName = hostNameSharedSecretName;
NSString *tempRegSharedSecretName = regSharedSecretName;
@ -1010,7 +1005,6 @@ MyDNSServiceAddServiceToRunLoop(MyDNSServiceState * query)
OSStatus err = noErr;
hostNameString = [self trimCharactersFromDomain:hostNameString];
browseDomainString = [self trimCharactersFromDomain:browseDomainString];
regDomainString = [self trimCharactersFromDomain:regDomainString];
tempHostNameSharedSecretName = [self trimCharactersFromDomain:tempHostNameSharedSecretName];
tempRegSharedSecretName = [self trimCharactersFromDomain:tempRegSharedSecretName];

View File

@ -3,9 +3,9 @@
Abstract: Interface to "ddnswriteconfig" setuid root tool.
Copyright: (c) Copyright 2005 Apple Computer, Inc. All rights reserved.
Copyright: (c) Copyright 2005-2015 Apple Inc. All rights reserved.
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
@ -19,7 +19,7 @@
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
@ -48,24 +48,23 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>
#include <AssertMacros.h>
#include <Security/Security.h>
extern char **environ;
Boolean gToolApproved = false;
static pid_t execTool(const char *args[])
// fork/exec and return new pid
{
pid_t child;
child = vfork();
if (child == 0)
int err = posix_spawn(&child, args[0], NULL, NULL, (char *const *)args, environ);
if (err)
{
execv(args[0], (char *const *)args);
printf("exec of %s failed; errno = %d\n", args[0], errno);
_exit(-1); // exec failed
printf("exec of %s failed; err = %d\n", args[0], err);
return -1;
}
else
return child;
@ -119,11 +118,14 @@ OSStatus EnsureToolInstalled(void)
{
char *installerargs[] = { toolSourcePath, NULL };
err = AuthorizationExecuteWithPrivileges(authRef, toolInstallerPath, 0, installerargs, (FILE**) NULL);
if (err == noErr) {
if (err == noErr)
{
int pid = wait(&status);
if (pid > 0 && WIFEXITED(status)) {
if (pid > 0 && WIFEXITED(status))
{
err = WEXITSTATUS(status);
if (err == noErr) {
if (err == noErr)
{
gToolApproved = true;
}
} else {
@ -181,7 +183,8 @@ static OSStatus ExecWithCmdAndParam(const char *subCmd, CFDataRef paramData)
write(commFD, buff, len);
child = execTool(args);
if (child > 0) {
if (child > 0)
{
int status;
waitpid(child, &status, 0);
if (WIFEXITED(status))

View File

@ -87,18 +87,23 @@ WriteArrayToDynDNS(CFStringRef arrayKey, CFArrayRef domainArray)
require_action(true == SCPreferencesLock( store, true), LockFailed, err=coreFoundationUnknownErr;);
origDict = SCPreferencesPathGetValue(store, scKey);
if (origDict) {
if (origDict)
{
dict = CFDictionaryCreateMutableCopy(NULL, 0, origDict);
}
if (!dict) {
if (!dict)
{
dict = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
}
require_action( dict != NULL, NoDict, err=memFullErr;);
if (CFArrayGetCount(domainArray) > 0) {
if (CFArrayGetCount(domainArray) > 0)
{
CFDictionarySetValue(dict, arrayKey, domainArray);
} else {
}
else
{
CFDictionaryRemoveValue(dict, arrayKey);
}
@ -138,10 +143,13 @@ readTaggedBlock(int fd, u_int32_t *pTag, u_int32_t *pLen, char **ppBuff)
require_action(*ppBuff != NULL, AllocFailed, result = -1;);
num = read(fd, *ppBuff, len);
if (num == (ssize_t)len) {
if (num == (ssize_t)len)
{
*pTag = tag;
*pLen = len;
} else {
}
else
{
free(*ppBuff);
result = -1;
}
@ -166,7 +174,8 @@ SetAuthInfo( int fd)
require( len == sizeof(AuthorizationExternalForm), ReadParamsFailed);
require( len == kAuthorizationExternalFormLength, ReadParamsFailed);
if (gAuthRef != 0) {
if (gAuthRef != 0)
{
(void) AuthorizationFree(gAuthRef, kAuthorizationFlagDefaults);
gAuthRef = 0;
}
@ -199,10 +208,15 @@ HandleWriteDomain(int fd, int domainType)
domainData = CFDataCreate(NULL, (UInt8 *)p, len);
domainArray = (CFArrayRef)[NSUnarchiver unarchiveObjectWithData:(NSData *)domainData];
CFRelease(domainData);
free(p);
if (domainType) {
if (domainType)
{
result = WriteArrayToDynDNS(SC_DYNDNS_REGDOMAINS_KEY, domainArray);
} else {
}
else
{
result = WriteArrayToDynDNS(SC_DYNDNS_BROWSEDOMAINS_KEY, domainArray);
}
@ -232,6 +246,8 @@ HandleWriteHostname(int fd)
domainData = CFDataCreate(NULL, (const UInt8 *)p, len);
domainArray = (CFArrayRef)[NSUnarchiver unarchiveObjectWithData:(NSData *)domainData];
result = WriteArrayToDynDNS(SC_DYNDNS_HOSTNAMES_KEY, domainArray);
CFRelease(domainData);
free(p);
ReadParamsFailed:
return result;
@ -341,6 +357,8 @@ SetKeychainEntry(int fd)
secretData = CFDataCreate(NULL, (UInt8 *)p, len);
secretDictionary = (CFDictionaryRef)[NSUnarchiver unarchiveObjectWithData:(NSData *)secretData];
CFRelease(secretData);
free(p);
keyNameString = (CFStringRef)CFDictionaryGetValue(secretDictionary, SC_DYNDNS_KEYNAME_KEY);
assert(keyNameString != NULL);
@ -356,9 +374,11 @@ SetKeychainEntry(int fd)
CFStringGetCString(secretString, secret, kDNSServiceMaxDomainName, kCFStringEncodingUTF8);
result = SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem);
if (result == noErr) {
if (result == noErr)
{
result = SecKeychainFindGenericPassword(NULL, strlen(domain), domain, 0, NULL, 0, NULL, &item);
if (result == noErr) {
if (result == noErr)
{
result = SecKeychainItemDelete(item);
if (result != noErr) fprintf(stderr, "SecKeychainItemDelete returned %d\n", result);
}

View File

@ -0,0 +1,32 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2015 Apple Inc. All rights reserved.
*/
#ifndef _DNS_SD_PRIVATE_H
#define _DNS_SD_PRIVATE_H
/* DNSServiceCreateDelegateConnection()
*
* Parameters:
*
* sdRef: A pointer to an uninitialized DNSServiceRef. Deallocating
* the reference (via DNSServiceRefDeallocate()) severs the
* connection and deregisters all records registered on this connection.
*
* pid : Process ID of the delegate
*
* uuid: UUID of the delegate
*
* Note that only one of the two arguments (pid or uuid) can be specified. If pid
* is zero, uuid will be assumed to be a valid value; otherwise pid will be used.
*
* return value: Returns kDNSServiceErr_NoError on success, otherwise returns
* an error code indicating the specific failure that occurred (in which
* case the DNSServiceRef is not initialized). kDNSServiceErr_NotAuth is
* returned to indicate that the calling process does not have entitlements
* to use this API.
*/
DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *sdRef, int32_t pid, uuid_t uuid);
#endif

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2012 Apple Inc. All rights reserved.
* Copyright (c) 2012-2015 Apple Inc. All rights reserved.
*
* PRIVATE DNSX CLIENT LIBRARY --FOR Apple Platforms ONLY OSX/iOS--
* Resides in /usr/lib/libdns_services.dylib
@ -10,10 +10,10 @@
#include "dns_xpc.h"
#include <xpc/xpc.h>
#include <Block.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#define LOG_NOW LOG_INFO
//*************************************************************************************************************
// Globals
@ -41,7 +41,7 @@ static void LogDebug(const char *prefix, xpc_object_t o)
return;
char *desc = xpc_copy_description(o);
syslog(LOG_INFO, "%s: %s", prefix, desc);
syslog(LOG_NOW, "%s: %s", prefix, desc);
free(desc);
}
@ -49,110 +49,146 @@ static void LogDebug(const char *prefix, xpc_object_t o)
void DNSXRefDeAlloc(DNSXConnRef connRef)
{
if (!connRef)
if (connRef == NULL)
{
syslog(LOG_WARNING, "dns_services: DNSXRefDeAlloc called with NULL DNSXConnRef");
syslog(LOG_WARNING, "dns_services DD: DNSXRefDeAlloc called with NULL DNSXConnRef");
return;
}
// Schedule this work on the internal library queue
dispatch_sync(connRef->lib_q, ^{
xpc_connection_set_event_handler((connRef)->conn_ref, ^(__unused xpc_object_t event){}); // ignore any more events
xpc_release(connRef->conn_ref);
connRef->conn_ref = NULL;
dispatch_release(connRef->lib_q);
connRef->lib_q = NULL;
connRef->AppCallBack = NULL;
dispatch_release(connRef->client_q);
syslog(LOG_NOW, "dns_services DD: DNSXRefDeAlloc successfully DeAllocated conn_ref & lib_q");
dispatch_async((connRef)->client_q, ^{
dispatch_release(connRef->client_q);
connRef->client_q = NULL;
free(connRef);
syslog(LOG_NOW, "dns_services DD: DNSXRefDeAlloc successfully DeAllocated client_q & freed connRef");
});
});
dispatch_release(connRef->lib_q);
free(connRef);
syslog(LOG_INFO, "dns_services: DNSXRefDeAlloc successfully DeAllocated connRef");
// DO NOT reference connRef after this comment, as it may have been freed
syslog(LOG_NOW, "dns_services DD: DNSXRefDeAlloc successfully DeAllocated connRef");
}
// Sends the Msg(Dictionary) to the Server
static DNSXErrorType SendMsgToServer(DNSXConnRef *connRef, xpc_object_t msg, bool old_conn)
// Sends the Msg(Dictionary) to the Server Daemon
static DNSXErrorType SendMsgToServer(DNSXConnRef connRef, xpc_object_t msg)
{
DNSXErrorType errx = kDNSX_NoError;
LogDebug("dns_services: SendMsgToServer", msg);
LogDebug("dns_services DD: SendMsgToServer Sending msg to Daemon", msg);
xpc_connection_set_event_handler((*connRef)->conn_ref, ^(xpc_object_t recv_msg)
xpc_connection_send_message_with_reply((connRef)->conn_ref, msg, (connRef)->lib_q, ^(xpc_object_t recv_msg)
{
xpc_type_t type = xpc_get_type(recv_msg);
if (type == XPC_TYPE_DICTIONARY)
{
LogDebug("dns_services: SendMsgToServer SUCCESS CALLBACK FROM SERVER", recv_msg);
syslog(LOG_INFO, "dns_services: Successfully Sent Msg to the Daemon");
LogDebug("dns_services DD: SendMsgToServer Received reply msg from Daemon", recv_msg);
uint64_t daemon_status = xpc_dictionary_get_uint64(recv_msg, kDNSDaemonReply);
// Schedule the AppCallBacks on the Client Specified Queue
switch (daemon_status)
if (connRef == NULL || connRef->client_q == NULL || connRef->AppCallBack == NULL)
{
case kDNSDaemonEngaged:
dispatch_async((*connRef)->client_q, ^{
((DNSXEnableProxyReply)(*connRef)->AppCallBack)((*connRef), kDNSX_Engaged);
});
break;
case kDNSMsgReceived:
dispatch_async((*connRef)->client_q, ^{
((DNSXEnableProxyReply)(*connRef)->AppCallBack)((*connRef), kDNSX_NoError);
});
break;
default:
dispatch_async((*connRef)->client_q, ^{
((DNSXEnableProxyReply)(*connRef)->AppCallBack)((*connRef), kDNSX_UnknownErr);
});
break;
}
// If connRef is bad, do not schedule any callbacks to the client
syslog(LOG_WARNING, "dns_services DD: SendMsgToServer: connRef is BAD Daemon status code [%llu]", daemon_status);
}
else
{
LogDebug("dns_services: SendMsgToServer UNEXPECTED CALLBACK FROM SERVER", recv_msg);
syslog(LOG_WARNING, "dns_services: Connection failed since NO privileges to access service OR Daemon NOT Running");
dispatch_async((*connRef)->client_q, ^{
((DNSXEnableProxyReply)(*connRef)->AppCallBack)((*connRef), kDNSX_DaemonNotRunning);
switch (daemon_status)
{
case kDNSMsg_NoError:
dispatch_async((connRef)->client_q, ^{
if (connRef->AppCallBack != NULL)
((DNSXEnableProxyReply)connRef->AppCallBack)(connRef, kDNSX_NoError);
});
break;
case kDNSMsg_BadArg:
dispatch_async((connRef)->client_q, ^{
if (connRef->AppCallBack != NULL)
((DNSXEnableProxyReply)connRef->AppCallBack)(connRef, kDNSX_BadParam);
});
break;
default:
dispatch_async((connRef)->client_q, ^{
if (connRef->AppCallBack != NULL)
((DNSXEnableProxyReply)connRef->AppCallBack)(connRef, kDNSX_UnknownErr);
});
break;
}
}
}
else
{
syslog(LOG_WARNING, "dns_services DD: SendMsgToServer Received unexpected reply from daemon [%s]",
xpc_dictionary_get_string(recv_msg, XPC_ERROR_KEY_DESCRIPTION));
LogDebug("dns_services DD: SendMsgToServer Unexpected Reply contents", recv_msg);
}
});
// To prevent Over-Resume of a connection
if (!old_conn)
xpc_connection_resume((*connRef)->conn_ref);
xpc_connection_send_message((*connRef)->conn_ref, msg);
if (!errx)
syslog(LOG_INFO, "dns_services: SendMSgToServer sent Msg Dict successfully to Daemon");
return errx;
}
// Creates a new DNSX Connection Reference(DNSXConnRef).
// If DNSXConnRef exists, you may want to use that depending on the use case
static DNSXErrorType InitConnection(DNSXConnRef *connRef, const char *servname, dispatch_queue_t clientq, void *AppCallBack)
// Creates a new DNSX Connection Reference(DNSXConnRef)
static DNSXErrorType InitConnection(DNSXConnRef *connRefOut, const char *servname, dispatch_queue_t clientq, void *AppCallBack)
{
if (!connRef)
{
syslog(LOG_WARNING, "dns_services: InitConnection() called with NULL DNSXConnRef");
if (connRefOut == NULL)
return kDNSX_BadParam;
}
*connRef = malloc(sizeof(struct _DNSXConnRef_t));
if (!(*connRef))
// Use a DNSXConnRef on the stack to be captured in the blocks below, rather than capturing the DNSXConnRef* owned by the client
DNSXConnRef connRef = malloc(sizeof(struct _DNSXConnRef_t));
if (connRef == NULL)
{
syslog(LOG_WARNING, "dns_services: InitConnection() No memory to allocate");
syslog(LOG_WARNING, "dns_services DD: InitConnection() No memory to allocate!");
return kDNSX_NoMem;
}
// Initialize the DNSXConnRef
dispatch_retain(clientq);
(*connRef)->client_q = clientq;
(*connRef)->AppCallBack = AppCallBack;
(*connRef)->lib_q = dispatch_queue_create("com.apple.mDNSResponder.libdns_services.q", NULL);
(*connRef)->conn_ref = xpc_connection_create_mach_service(servname, (*connRef)->lib_q, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
connRef->client_q = clientq;
connRef->AppCallBack = AppCallBack;
connRef->lib_q = dispatch_queue_create("com.apple.mDNSResponder.libdns_services.q", DISPATCH_QUEUE_SERIAL);
connRef->conn_ref = xpc_connection_create_mach_service(servname, connRef->lib_q, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
if (connRef->conn_ref == NULL || connRef->lib_q == NULL)
{
syslog(LOG_WARNING, "dns_services DD: InitConnection() conn_ref/lib_q is NULL");
if (connRef != NULL)
free(connRef);
return kDNSX_NoMem;
}
xpc_connection_set_event_handler(connRef->conn_ref, ^(xpc_object_t event)
{
if (connRef == NULL || connRef->client_q == NULL || connRef->AppCallBack == NULL)
{
// If connRef is bad, do not schedule any callbacks to the client
syslog(LOG_WARNING, "dns_services DD: InitConnection: connRef is BAD Unexpected Connection Error [%s]",
xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
}
else
{
syslog(LOG_WARNING, "dns_services DD: InitConnection: Unexpected Connection Error [%s] Ping the client",
xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
dispatch_async(connRef->client_q, ^{
if (connRef->AppCallBack != NULL)
((DNSXEnableProxyReply)connRef->AppCallBack)(connRef, kDNSX_DaemonNotRunning);
});
}
});
xpc_connection_resume(connRef->conn_ref);
*connRefOut = connRef;
syslog(LOG_INFO, "dns_services: InitConnection() successfully create a new DNSXConnRef");
return kDNSX_NoError;
}
@ -161,37 +197,37 @@ DNSXErrorType DNSXEnableProxy(DNSXConnRef *connRef, DNSProxyParameters proxypara
{
DNSXErrorType errx = kDNSX_NoError;
bool old_conn = false;
// Sanity Checks
if (!connRef || !callBack || !clientq)
if (connRef == NULL || callBack == NULL || clientq == NULL)
{
syslog(LOG_WARNING, "dns_services: DNSXEnableProxy called with NULL DNSXConnRef OR Callback OR ClientQ parameter");
syslog(LOG_WARNING, "dns_services DD: DNSXEnableProxy called with NULL DNSXConnRef OR Callback OR ClientQ parameter");
return kDNSX_BadParam;
}
// If no connRef, get it from InitConnection()
if (!*connRef)
// Get connRef from InitConnection()
if (*connRef == NULL)
{
errx = InitConnection(connRef, kDNSProxyService, clientq, callBack);
if (errx) // On error InitConnection() leaves *connRef set to NULL
{
syslog(LOG_WARNING, "dns_services: Since InitConnection() returned %d error returning w/o sending msg", errx);
syslog(LOG_WARNING, "dns_services DD: Since InitConnection() returned %d error returning w/o sending msg", errx);
return errx;
}
}
else // Client already has a valid connRef
else // Client already has a connRef and this is not valid use for this SPI
{
old_conn = true;
syslog(LOG_WARNING, "dns_services DD: Client already has a valid connRef! This is incorrect usage from the client");
return kDNSX_BadParam;
}
// Create Dictionary To Send
xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
if (!dict)
if (dict == NULL)
{
syslog(LOG_WARNING, "dns_services: DNSXEnableProxy could not create the Msg Dict To Send!");
syslog(LOG_WARNING, "dns_services DD: DNSXEnableProxy could not create the Msg Dict To Send!");
DNSXRefDeAlloc(*connRef);
return kDNSX_DictError;
return kDNSX_NoMem;
}
xpc_dictionary_set_uint64(dict, kDNSProxyParameters, proxyparam);
@ -204,8 +240,9 @@ DNSXErrorType DNSXEnableProxy(DNSXConnRef *connRef, DNSProxyParameters proxypara
xpc_dictionary_set_uint64(dict, kDNSOutIfindex, outIfindex);
errx = SendMsgToServer(connRef, dict, old_conn);
errx = SendMsgToServer(*connRef, dict);
xpc_release(dict);
dict = NULL;
return errx;
}

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2012 Apple Inc. All rights reserved.
* Copyright (c) 2012-2015 Apple Inc. All rights reserved.
*
*
* @header Interface to DNSX SPI
@ -21,15 +21,12 @@ 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
kDNSX_NoMem = -65539, /* No Memory */
kDNSX_BadParam = -65540, /* Client passes invalid arg/Bad use of SPI */
kDNSX_DaemonNotRunning = -65563 /* Daemon not running */
} DNSXErrorType;
// A max of 5 input interfaces can be processed at one time
// A max of 5 input interfaces can be processed
#define MaxInputIf 5
#define IfIndex uint64_t
#define kDNSIfindexAny 0
@ -42,10 +39,10 @@ typedef enum
} DNSProxyParameters;
/*********************************************************************************************
*
* Enable DNS Proxy Functionality
*
*********************************************************************************************/
*
* Enable DNS Proxy Functionality
*
*********************************************************************************************/
/* DNSXEnableProxy : Turns ON the DNS Proxy (Details below)
*
@ -54,8 +51,7 @@ typedef enum
* 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.
* failure that occurred.
*
*/
@ -67,13 +63,13 @@ typedef void (*DNSXEnableProxyReply)
/* 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()
* Enables the DNS Proxy functionality which will remain ON until the client explicitly turns it OFF
* by passing the returned DNSXConnRef to DNSXRefDeAlloc(), or the client exits or crashes.
*
* 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.
* connRef: A pointer to DNSXConnRef that is initialized to NULL.
* 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
@ -88,16 +84,19 @@ typedef void (*DNSXEnableProxyReply)
* outIfindex: Output interface on which the query will be forwarded.
* Passing kDNSIfindexAny causes DNS Queries to be sent on the primary interface.
*
* Note: It is the responsibility of the client to ensure the input/output interface
* indexes are valid.
*
* 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
* Note: callback may be invoked more than once, For e.g. 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)
* return an error (such as kDNSX_DaemonNotRunning)
*
*/
@ -109,7 +108,7 @@ DNSXErrorType DNSXEnableProxy
IfIndex outIfindex,
dispatch_queue_t clientq,
DNSXEnableProxyReply callBack
);
);
/* DNSXRefDeAlloc()
*
@ -121,4 +120,4 @@ DNSXErrorType DNSXEnableProxy
*/
void DNSXRefDeAlloc(DNSXConnRef connRef);
#endif /* _DNS_SERVICES_H */
#endif

View File

@ -26,8 +26,8 @@
typedef enum
{
kDNSMsgReceived = 0,
kDNSDaemonEngaged
kDNSMsg_NoError = 0,
kDNSMsg_BadArg
} DaemonReplyStatusCodes;
#endif // DNS_XPC_H

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2012 Apple Inc. All rights reserved.
* Copyright (c) 2012-2015 Apple Inc. All rights reserved.
*
* xpc_services.c
* mDNSResponder
@ -90,7 +90,7 @@ mDNSlocal void handle_dps_request(xpc_object_t req)
xpc_object_t reply = xpc_dictionary_create(NULL, NULL, 0);
if (reply)
{
xpc_dictionary_set_uint64(reply, kDNSDaemonReply, kDNSDaemonEngaged);
xpc_dictionary_set_uint64(reply, kDNSDaemonReply, kDNSMsg_BadArg);
xpc_connection_send_message(remote_conn, reply);
xpc_release(reply);
}
@ -105,11 +105,12 @@ mDNSlocal void handle_dps_request(xpc_object_t req)
}
}
xpc_object_t response = xpc_dictionary_create_reply(req);
// Return Success Status to the client
xpc_object_t response = xpc_dictionary_create(NULL, NULL, 0);
if (response)
{
xpc_dictionary_set_uint64(response, kDNSDaemonReply, kDNSMsgReceived);
xpc_dictionary_set_uint64(response, kDNSDaemonReply, kDNSMsg_NoError);
xpc_connection_send_message(remote_conn, response);
xpc_release(response);
}
@ -155,17 +156,22 @@ mDNSlocal mDNSBool IsEntitled(xpc_connection_t conn, const char *password)
LogMsg("IsEntitled: Client Entitlement is NULL");
}
if (!entitled)
LogMsg("IsEntitled: DNSProxyService Client is missing Entitlement!");
return entitled;
}
mDNSlocal void accept_dps_client(xpc_connection_t conn)
{
uid_t euid;
euid = xpc_connection_get_euid(conn);
uid_t c_euid;
int c_pid;
c_euid = xpc_connection_get_euid(conn);
c_pid = xpc_connection_get_pid(conn);
if (euid != 0 || !IsEntitled(conn, kDNSProxyService))
if (c_euid != 0 || !IsEntitled(conn, kDNSProxyService))
{
LogMsg("accept_dps_client: DNSProxyService Client Pid[%d] is missing Entitlement or is not root!", (int) xpc_connection_get_pid(conn));
LogMsg("accept_dps_client: DNSProxyService Client PID[%d] is missing Entitlement or is not running as root!", c_pid);
xpc_connection_cancel(conn);
return;
}
@ -180,16 +186,16 @@ mDNSlocal void accept_dps_client(xpc_connection_t conn)
{
handle_dps_request(req_msg);
}
// We hit the case below only if Client Terminated DPS Connection OR Crashed
else
else // We hit this case ONLY if Client Terminated DPS Connection OR Crashed
{
LogInfo("accept_dps_client: DPS Client %p teared down the connection or Crashed", (void *) conn);
// Only the Client that has activated DPS should be able to terminate it
if (((int)xpc_connection_get_pid(conn)) == dps_client_pid)
if (c_pid == dps_client_pid)
handle_dps_terminate();
xpc_release(conn);
}
});
xpc_connection_resume(conn);
}
@ -215,8 +221,7 @@ mDNSlocal void init_dnsproxy_service(void)
LogInfo("init_dnsproxy_service: New DNSProxyService Client %p", eventmsg);
accept_dps_client(eventmsg);
}
// Ideally, we would never hit the cases below
else if (type == XPC_TYPE_ERROR)
else if (type == XPC_TYPE_ERROR) // Ideally, we would never hit these cases
{
LogMsg("init_dnsproxy_service: XPCError: %s", xpc_dictionary_get_string(eventmsg, XPC_ERROR_KEY_DESCRIPTION));
return;
@ -227,6 +232,7 @@ mDNSlocal void init_dnsproxy_service(void)
return;
}
});
xpc_connection_resume(dps_listener);
}

View File

@ -0,0 +1,187 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mDNSEmbeddedAPI.h"
#include <arpa/inet.h>
#include <dlfcn.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/socket.h>
#include <Symptoms/SymptomReporter.h>
#define SYMPTOM_REPORTER_mDNSResponder_NUMERIC_ID 101
#define SYMPTOM_REPORTER_mDNSResponder_TEXT_ID "com.apple.mDNSResponder"
#define SYMPTOM_DNS_NO_REPLIES 0x00065001
#define SYMPTOM_DNS_RESUMED_RESPONDING 0x00065002
static symptom_framework_t symptomReporter;
static symptom_framework_t (*symptom_framework_init_f)(symptom_ident_t id, const char *originator_string) = mDNSNULL;
static symptom_t (*symptom_new_f)(symptom_framework_t framework, symptom_ident_t id) = mDNSNULL;
static int (*symptom_set_additional_qualifier_f)(symptom_t symptom, uint32_t qualifier_type, size_t qualifier_len, void *qualifier_data) = mDNSNULL;
static int (*symptom_send_f)(symptom_t symptom) = mDNSNULL;
mDNSlocal mStatus SymptomReporterInitCheck(void)
{
mStatus err;
static mDNSBool isInitialized = mDNSfalse;
static void *symptomReporterLib = mDNSNULL;
static const char path[] = "/System/Library/PrivateFrameworks/Symptoms.framework/Frameworks/SymptomReporter.framework/SymptomReporter";
if (!isInitialized)
{
if (!symptomReporterLib)
{
symptomReporterLib = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
if (!symptomReporterLib)
goto exit;
}
if (!symptom_framework_init_f)
{
symptom_framework_init_f = dlsym(symptomReporterLib, "symptom_framework_init");
if (!symptom_framework_init_f)
goto exit;
}
if (!symptom_new_f)
{
symptom_new_f = dlsym(symptomReporterLib, "symptom_new");
if (!symptom_new_f)
goto exit;
}
if (!symptom_set_additional_qualifier_f)
{
symptom_set_additional_qualifier_f = dlsym(symptomReporterLib, "symptom_set_additional_qualifier");
if (!symptom_set_additional_qualifier_f)
goto exit;
}
if (!symptom_send_f)
{
symptom_send_f = dlsym(symptomReporterLib, "symptom_send");
if (!symptom_send_f)
goto exit;
}
symptomReporter = symptom_framework_init_f(SYMPTOM_REPORTER_mDNSResponder_NUMERIC_ID, SYMPTOM_REPORTER_mDNSResponder_TEXT_ID);
isInitialized = mDNStrue;
}
exit:
err = isInitialized ? mStatus_NoError : mStatus_NotInitializedErr;
return err;
}
mDNSlocal mStatus SymptomReporterReportDNSReachability(const mDNSAddr *addr, mDNSBool isReachable)
{
mStatus err;
symptom_t symptom;
struct sockaddr_storage sockAddr;
size_t sockAddrSize;
LogInfo("SymptomReporterReportDNSReachability: DNS server %#a is %sreachable", addr, isReachable ? "" : "un");
if (addr->type == mDNSAddrType_IPv4)
{
struct sockaddr_in *sin = (struct sockaddr_in *)&sockAddr;
sockAddrSize = sizeof(*sin);
mDNSPlatformMemZero(sin, sockAddrSize);
sin->sin_len = sockAddrSize;
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = addr->ip.v4.NotAnInteger;
}
else if (addr->type == mDNSAddrType_IPv6)
{
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&sockAddr;
sockAddrSize = sizeof(*sin6);
mDNSPlatformMemZero(sin6, sockAddrSize);
sin6->sin6_len = sockAddrSize;
sin6->sin6_family = AF_INET6;
sin6->sin6_addr = *(struct in6_addr *)&addr->ip.v6;
}
else
{
LogMsg("SymptomReporterReportDNSReachability: addr is not an IPv4 or IPv6 address!");
err = mStatus_BadParamErr;
goto exit;
}
symptom = symptom_new_f(symptomReporter, isReachable ? SYMPTOM_DNS_RESUMED_RESPONDING : SYMPTOM_DNS_NO_REPLIES);
symptom_set_additional_qualifier_f(symptom, 1, sockAddrSize, (void *)&sockAddr);
symptom_send_f(symptom);
err = mStatus_NoError;
exit:
return err;
}
mDNSexport mStatus SymptomReporterDNSServerReachable(mDNS *const m, const mDNSAddr *addr)
{
mStatus err;
DNSServer *s;
mDNSBool found = mDNSfalse;
err = SymptomReporterInitCheck();
if (err != mStatus_NoError)
goto exit;
for (s = m->DNSServers; s; s = s->next)
{
if (s->flags & DNSServer_FlagDelete)
continue;
if ((s->flags & DNSServer_FlagUnreachable) && mDNSSameAddress(addr, &s->addr))
{
s->flags &= ~DNSServer_FlagUnreachable;
NumUnreachableDNSServers--;
found = mDNStrue;
}
}
if (!found)
{
err = mStatus_NoSuchNameErr;
goto exit;
}
err = SymptomReporterReportDNSReachability(addr, mDNStrue);
exit:
return err;
}
mDNSexport mStatus SymptomReporterDNSServerUnreachable(DNSServer *s)
{
mStatus err;
err = SymptomReporterInitCheck();
if (err != mStatus_NoError)
goto exit;
if ((s->flags & DNSServer_FlagDelete) || (s->flags & DNSServer_FlagUnreachable))
goto exit;
s->flags |= DNSServer_FlagUnreachable;
NumUnreachableDNSServers++;
err = SymptomReporterReportDNSReachability(&s->addr, mDNSfalse);
exit:
return err;
}

View File

@ -1,33 +0,0 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2013 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mDNSMacOSX.h"
#include <SystemConfiguration/VPNAppLayerPrivate.h>
mDNSexport mDNSs32 mDNSPlatformGetServiceID(mDNS *const m, DNSQuestion *q)
{
(void) m;
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;
}

View File

@ -1,2 +0,0 @@
PUBLIC_HEADERS_FOLDER_PATH = /usr/include
PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include

View File

@ -35,11 +35,9 @@
<integer>438</integer>
</dict>
</dict>
<key>EnableTransactions</key>
<true/>
<key>BeginTransactionAtShutdown</key>
<true/>
<key>POSIXSpawnType</key>
<string>Interactive</string>
<key>EnablePressuredExit</key>
<false/>
</dict>
</plist>

View File

@ -15,10 +15,6 @@
<key>com.apple.mDNSResponderHelper</key>
<true/>
</dict>
<key>EnableTransactions</key>
<true/>
<key>BeginTransactionAtShutdown</key>
<true/>
<key>POSIXSpawnType</key>
<string>Interactive</string>
</dict>

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2011 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,7 +13,6 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <mach/mach.h>
@ -26,7 +25,6 @@
#include <fcntl.h>
#include <launch.h>
#include <launch_priv.h> // for launch_socket_service_check_in()
#include <vproc.h>
#include <pwd.h>
#include <sys/event.h>
#include <pthread.h>
@ -51,16 +49,33 @@
#include "../mDNSMacOSX/DNSServiceDiscovery.h"
#include "helper.h"
#if TARGET_OS_EMBEDDED
#include "Metrics.h"
#endif
static aslclient log_client = NULL;
static aslmsg log_msg = NULL;
// Used on Embedded Side for Reading mDNSResponder Managed Preferences Profile
// Used on iOS ONLY for reading mDNSResponder Managed Preferences Profile
#if TARGET_OS_EMBEDDED
#define kmDNSEnableLoggingStr CFSTR("EnableLogging")
#define kmDNSResponderPrefIDStr "com.apple.mDNSResponder.plist"
#define kmDNSResponderPrefID CFSTR(kmDNSResponderPrefIDStr)
#endif
// Used on OSX(10.11.x onwards) for manipulating mDNSResponder program arguments
#if APPLE_OSX_mDNSResponder && !TARGET_OS_EMBEDDED
// plist file to read the user's preferences
#define kProgramArguments CFSTR("/Library/Preferences/com.apple.mDNSResponder.plist")
// possible arguments for external customers
#define kDebugLogging CFSTR("DebugLogging")
#define kUnicastPacketLogging CFSTR("UnicastPacketLogging")
#define kAlwaysAppendSearchDomains CFSTR("AlwaysAppendSearchDomains")
#define kNoMulticastAdvertisements CFSTR("NoMulticastAdvertisements")
#define kStrictUnicastOrdering CFSTR("StrictUnicastOrdering")
#endif
//*************************************************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - Globals
@ -68,12 +83,13 @@ static aslmsg log_msg = NULL;
static mDNS_PlatformSupport PlatformStorage;
// Start off with a default cache of 16K (99 records)
// Each time we grow the cache we add another 99 records
// 99 * 164 = 16236 bytes.
// This fits in four 4kB pages, with 148 bytes spare for memory block headers and similar overhead
#define RR_CACHE_SIZE ((16*1024) / sizeof(CacheRecord))
// Start off with a default cache of 32K (141 records of 232 bytes each)
// Each time we grow the cache we add another 141 records
// 141 * 164 = 32712 bytes.
// This fits in eight 4kB pages, with 56 bytes spare for memory block headers and similar overhead
#define RR_CACHE_SIZE ((32*1024) / sizeof(CacheRecord))
static CacheEntity rrcachestorage[RR_CACHE_SIZE];
struct CompileTimeAssertionChecks_RR_CACHE_SIZE { char a[(RR_CACHE_SIZE >= 141) ? 1 : -1]; };
static mach_port_t m_port = MACH_PORT_NULL;
@ -85,7 +101,7 @@ static mach_port_t signal_port = MACH_PORT_NULL;
#endif // MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
static dnssd_sock_t *launchd_fds = mDNSNULL;
static mDNSu32 launchd_fds_count = 0;
static size_t launchd_fds_count = 0;
// mDNS Mach Message Timeout, in milliseconds.
// We need this to be short enough that we don't deadlock the mDNSResponder if a client
@ -214,22 +230,16 @@ static KQSocketEventSource *gEventSources;
char _malloc_options[] = "AXZ";
mDNSexport void LogMemCorruption(const char *format, ...)
mDNSlocal void validatelists(mDNS *const m, bool checkCRActiveQuestion)
{
char buffer[512];
va_list ptr;
va_start(ptr,format);
buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
va_end(ptr);
LogMsg("!!!! %s !!!!", buffer);
NotifyOfElusiveBug("Memory Corruption", buffer);
#if ForceAlerts
*(long*)0 = 0; // Trick to crash and get a stack trace right here, if that's what we want
#if TARGET_OS_WATCH
mDNSu32 NumAllInterfaceRecords = 0;
mDNSu32 NumAllInterfaceQuestions = 0;
#else
mDNSu32 NumAllInterfaceRecords = 1;
mDNSu32 NumAllInterfaceQuestions = 1;
#endif
}
mDNSlocal void validatelists(mDNS *const m)
{
// Check local lists
KQSocketEventSource *k;
for (k = gEventSources; k; k=k->next)
@ -269,11 +279,15 @@ mDNSlocal void validatelists(mDNS *const m)
if (rr->resrec.name != &rr->namestorage)
LogMemCorruption("ResourceRecords list: %p name %p does not point to namestorage %p %##s",
rr, rr->resrec.name->c, rr->namestorage.c, rr->namestorage.c);
if (!AuthRecord_uDNS(rr) && !RRLocalOnly(rr)) NumAllInterfaceRecords++;
}
for (rr = m->DuplicateRecords; rr; rr=rr->next)
{
if (rr->next == (AuthRecord *)~0 || rr->resrec.RecordType == 0 || rr->resrec.RecordType == 0xFF)
LogMemCorruption("DuplicateRecords list: %p is garbage (%X)", rr, rr->resrec.RecordType);
if (!AuthRecord_uDNS(rr) && !RRLocalOnly(rr)) NumAllInterfaceRecords++;
}
rr = m->NewLocalRecords;
if (rr)
@ -287,9 +301,14 @@ mDNSlocal void validatelists(mDNS *const m)
DNSQuestion *q;
for (q = m->Questions; q; q=q->next)
{
if (q->next == (DNSQuestion*)~0 || q->ThisQInterval == (mDNSs32) ~0)
LogMemCorruption("Questions list: %p is garbage (%lX %p)", q, q->ThisQInterval, q->next);
if (q->InterfaceID != mDNSInterface_LocalOnly && q->InterfaceID != mDNSInterface_P2P && mDNSOpaque16IsZero(q->TargetQID))
NumAllInterfaceQuestions++;
}
if (checkCRActiveQuestion) {
CacheGroup *cg;
CacheRecord *cr;
mDNSu32 slot;
@ -303,6 +322,7 @@ mDNSlocal void validatelists(mDNS *const m)
if (!q) LogMemCorruption("Cache slot %lu: CRActiveQuestion %p not in m->Questions list %s", slot, cr->CRActiveQuestion, CRDisplayString(m, cr));
}
}
}
// Check core uDNS lists
udns_validatelists(m);
@ -317,6 +337,14 @@ mDNSlocal void validatelists(mDNS *const m)
for (t = m->TunnelClients; t; t=t->next)
if (t->next == (ClientTunnel *)~0 || t->dstname.c[0] > 63)
LogMemCorruption("m->TunnelClients: %p is garbage (%d)", t, t->dstname.c[0]);
#if TARGET_OS_WATCH
if (m->NumAllInterfaceRecords != NumAllInterfaceRecords)
LogMemCorruption("NumAllInterfaceRecords is %d should be %d", m->NumAllInterfaceRecords, NumAllInterfaceRecords);
if (m->NumAllInterfaceQuestions != NumAllInterfaceQuestions)
LogMemCorruption("NumAllInterfaceQuestions is %d should be %d", m->NumAllInterfaceQuestions, NumAllInterfaceQuestions);
#endif
}
mDNSexport void *mallocL(char *msg, unsigned int size)
@ -327,13 +355,13 @@ mDNSexport void *mallocL(char *msg, unsigned int size)
{ LogMsg("malloc( %s : %d ) failed", msg, size); return(NULL); }
else
{
if (size > 24000) LogMsg("malloc( %s : %lu ) = %p suspiciously large", msg, size, &mem[2]);
else if (MACOSX_MDNS_MALLOC_DEBUGGING >= 2) LogMsg("malloc( %s : %lu ) = %p", msg, size, &mem[2]);
if (size > 32768) LogMsg("malloc( %s : %lu ) @ %p suspiciously large", msg, size, &mem[2]);
else if (MACOSX_MDNS_MALLOC_DEBUGGING >= 2) LogMsg("malloc( %s : %lu ) @ %p", msg, size, &mem[2]);
mem[0] = 0xDEAD1234;
mem[1] = size;
//mDNSPlatformMemZero(&mem[2], size);
memset(&mem[2], 0xFF, size);
validatelists(&mDNSStorage);
validatelists(&mDNSStorage, true);
return(&mem[2]);
}
}
@ -345,12 +373,13 @@ mDNSexport void freeL(char *msg, void *x)
else
{
mDNSu32 *mem = ((mDNSu32 *)x) - 2;
if (mem[0] != 0xDEAD1234) { LogMsg("free( %s @ %p ) !!!! NOT ALLOCATED !!!!", msg, &mem[2]); return; }
if (mem[1] > 24000) LogMsg("free( %s : %ld @ %p) suspiciously large", msg, mem[1], &mem[2]);
if (mem[0] == 0xDEADDEAD) { LogMemCorruption("free( %s : %lu @ %p ) !!!! ALREADY DISPOSED !!!!", msg, mem[1], &mem[2]); return; }
if (mem[0] != 0xDEAD1234) { LogMemCorruption("free( %s : %lu @ %p ) !!!! NEVER ALLOCATED !!!!", msg, mem[1], &mem[2]); return; }
if (mem[1] > 32768) LogMsg("free( %s : %lu @ %p) suspiciously large", msg, mem[1], &mem[2]);
else if (MACOSX_MDNS_MALLOC_DEBUGGING >= 2) LogMsg("free( %s : %ld @ %p)", msg, mem[1], &mem[2]);
//mDNSPlatformMemZero(mem, sizeof(mDNSu32) * 2 + mem[1]);
memset(mem, 0xFF, sizeof(mDNSu32) * 2 + mem[1]);
validatelists(&mDNSStorage);
mem[0] = 0xDEADDEAD;
memset(mem+2, 0xFF, mem[1]);
validatelists(&mDNSStorage, false);
free(mem);
}
}
@ -1272,6 +1301,8 @@ mDNSlocal void mDNSPreferencesSetNames(mDNS *const m, int key, domainlabel *old,
!SameDomainLabelCS(old->c, prevold->c) ||
!SameDomainLabelCS(new->c, prevnew->c))
{
// Work around bug radar:21397654
#ifndef __clang_analyzer__
if (old)
*prevold = *old;
else
@ -1280,6 +1311,7 @@ mDNSlocal void mDNSPreferencesSetNames(mDNS *const m, int key, domainlabel *old,
*prevnew = *new;
else
prevnew->c[0] = 0;
#endif
mDNSPreferencesSetName(key, old, new);
}
else
@ -1319,6 +1351,12 @@ mDNSlocal void mDNS_StatusCallback(mDNS *const m, mStatus result)
else if (result == mStatus_GrowCache)
{
// Allocate another chunk of cache storage
static unsigned int allocated = 0;
#if TARGET_OS_IPHONE
if (allocated >= 1000000) return; // For now we limit the cache to at most 1MB on iOS devices
#endif
allocated += sizeof(CacheEntity) * RR_CACHE_SIZE;
// LogMsg("GrowCache %d * %d = %d; total so far %6u", sizeof(CacheEntity), RR_CACHE_SIZE, sizeof(CacheEntity) * RR_CACHE_SIZE, allocated);
CacheEntity *storage = mallocL("mStatus_GrowCache", sizeof(CacheEntity) * RR_CACHE_SIZE);
//LogInfo("GrowCache %d * %d = %d", sizeof(CacheEntity), RR_CACHE_SIZE, sizeof(CacheEntity) * RR_CACHE_SIZE);
if (storage) mDNS_GrowCache(m, storage, RR_CACHE_SIZE);
@ -1454,7 +1492,7 @@ mDNSlocal mStatus UpdateRecord(ServiceRecordSet *srs, mach_port_t client, AuthRe
{
errormsg = "mDNS_Update";
freeL("RData", newrdata);
return err;
goto fail;
}
return(mStatus_NoError);
@ -1544,6 +1582,7 @@ mDNSexport kern_return_t provide_DNSServiceRegistrationRemoveRecord_rpc(mach_por
if ((natural_t)e->ClientID == reference)
{
err = RemoveRecord(&si->srs, e, client);
if (err) { errormsg = "RemoveRecord failed"; goto fail; }
break;
}
}
@ -1708,6 +1747,7 @@ mDNSlocal void HandleSIG(int sig)
mDNSlocal void INFOCallback(void)
{
mDNSs32 utc = mDNSPlatformUTC();
const mDNSs32 now = mDNS_TimeNow(&mDNSStorage);
NetworkInterfaceInfoOSX *i;
DNSServer *s;
McastResolver *mr;
@ -1720,6 +1760,14 @@ mDNSlocal void INFOCallback(void)
LogMsg("---- BEGIN STATE LOG ---- %s %s %d", mDNSResponderVersionString, OSXVers ? "OSXVers" : "iOSVers", OSXVers ? OSXVers : iOSVers);
udsserver_info(&mDNSStorage);
LogMsgNoIdent("----- Platform Timers -----");
LogTimer("m->NextCacheCheck ", mDNSStorage.NextCacheCheck);
LogTimer("m->NetworkChanged ", mDNSStorage.NetworkChanged);
LogTimer("m->p->NotifyUser ", mDNSStorage.p->NotifyUser);
LogTimer("m->p->HostNameConflict ", mDNSStorage.p->HostNameConflict);
LogTimer("m->p->KeyChainTimer ", mDNSStorage.p->KeyChainTimer);
xpcserver_info(&mDNSStorage);
LogMsgNoIdent("----- KQSocketEventSources -----");
@ -1787,7 +1835,7 @@ mDNSlocal void INFOCallback(void)
s->DNSSECAware ? "DNSSECAware" : "!DNSSECAware");
}
}
mDNSs32 now = mDNS_TimeNow(&mDNSStorage);
LogMsgNoIdent("v4answers %d", mDNSStorage.p->v4answers);
LogMsgNoIdent("v6answers %d", mDNSStorage.p->v6answers);
LogMsgNoIdent("Last DNS Trigger: %d ms ago", (now - mDNSStorage.p->DNSTrigger));
@ -1800,6 +1848,9 @@ mDNSlocal void INFOCallback(void)
LogMsgNoIdent("Mcast Resolver %##s timeout %u", mr->domain.c, mr->timeout);
}
#if TARGET_OS_EMBEDDED
LogMetrics();
#endif
LogMsgNoIdent("Timenow 0x%08lX (%d)", (mDNSu32)now, now);
LogMsg("---- END STATE LOG ---- %s %s %d", mDNSResponderVersionString, OSXVers ? "OSXVers" : "iOSVers", OSXVers ? OSXVers : iOSVers);
@ -1963,10 +2014,6 @@ mDNSlocal void SignalCallback(CFMachPortRef port, void *msg, CFIndex size, void
KQueueLock(m);
switch(msg_header->msgh_id)
{
case SIGURG:
m->mDNSOppCaching = m->mDNSOppCaching ? mDNSfalse : mDNStrue;
LogMsg("SIGURG: Opportunistic Caching %s", m->mDNSOppCaching ? "Enabled" : "Disabled");
// FALL THROUGH to purge the cache so that we re-do the caching based on the new setting
case SIGHUP: {
mDNSu32 slot;
CacheGroup *cg;
@ -2144,7 +2191,6 @@ mDNSlocal kern_return_t mDNSDaemonInitialize(void)
mDNSSetupSignal(queue, SIGINFO);
mDNSSetupSignal(queue, SIGUSR1);
mDNSSetupSignal(queue, SIGUSR2);
mDNSSetupSignal(queue, SIGURG);
// Create a custom handler for doing the housekeeping work. This is either triggered
// by the timer or an event source
@ -2197,16 +2243,16 @@ mDNSlocal mDNSs32 mDNSDaemonIdle(mDNS *const m)
// mDNS_Execute() generates packets, including multicasts that are looped back to ourself.
// If we call mDNS_Execute() first, and generate packets, and then call mDNSMacOSXNetworkChanged() immediately afterwards
// we then systematically lose our own looped-back packets.
if (m->p->NetworkChanged && now - m->p->NetworkChanged >= 0) mDNSMacOSXNetworkChanged(m);
if (m->NetworkChanged && now - m->NetworkChanged >= 0) mDNSMacOSXNetworkChanged(m);
if (m->p->RequestReSleep && now - m->p->RequestReSleep >= 0) { m->p->RequestReSleep = 0; mDNSPowerRequest(0, 0); }
// 3. Call mDNS_Execute() to let mDNSCore do what it needs to do
mDNSs32 nextevent = mDNS_Execute(m);
if (m->p->NetworkChanged)
if (nextevent - m->p->NetworkChanged > 0)
nextevent = m->p->NetworkChanged;
if (m->NetworkChanged)
if (nextevent - m->NetworkChanged > 0)
nextevent = m->NetworkChanged;
if (m->p->KeyChainTimer)
if (nextevent - m->p->KeyChainTimer > 0)
@ -2411,6 +2457,7 @@ mDNSlocal mDNSBool AllowSleepNow(mDNS *const m, mDNSs32 now)
//interval = 48; // For testing
#if !TARGET_OS_EMBEDDED
#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
if (m->p->IOPMConnection) // If lightweight-wake capability is available, use that
{
@ -2423,7 +2470,7 @@ mDNSlocal mDNSBool AllowSleepNow(mDNS *const m, mDNSs32 now)
if (!Requirements) LogMsg("ScheduleNextWake: CFNumberCreate failed");
else
{
const void *OptionKeys[2] = { CFSTR("WakeDate"), CFSTR("Requirements") };
const void *OptionKeys[2] = { kIOPMAckDHCPRenewWakeDate, kIOPMAckSystemCapabilityRequirements };
const void *OptionVals[2] = { WakeDate, Requirements };
opts = CFDictionaryCreate(NULL, (void*)OptionKeys, (void*)OptionVals, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (!opts) LogMsg("ScheduleNextWake: CFDictionaryCreate failed");
@ -2434,7 +2481,8 @@ mDNSlocal mDNSBool AllowSleepNow(mDNS *const m, mDNSs32 now)
LogSPS("AllowSleepNow: Will request lightweight wakeup in %d seconds", interval);
}
else // else schedule the wakeup using the old API instead to
#endif
#endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
#endif // TARGET_OS_EMBEDDED
{
// If we wake within +/- 30 seconds of our requested time we'll assume the system woke for us,
// so we should put it back to sleep. To avoid frustrating the user, we always request at least
@ -2594,9 +2642,9 @@ mDNSlocal void KQWokenFlushBytes(int fd, __unused short filter, __unused void *c
mDNSlocal void SetLowWater(const KQSocketSet *const k, const int r)
{
if (setsockopt(k->sktv4, SOL_SOCKET, SO_RCVLOWAT, &r, sizeof(r)) < 0)
if (k->sktv4 >=0 && setsockopt(k->sktv4, SOL_SOCKET, SO_RCVLOWAT, &r, sizeof(r)) < 0)
LogMsg("SO_RCVLOWAT IPv4 %d error %d errno %d (%s)", k->sktv4, r, errno, strerror(errno));
if (setsockopt(k->sktv6, SOL_SOCKET, SO_RCVLOWAT, &r, sizeof(r)) < 0)
if (k->sktv6 >=0 && setsockopt(k->sktv6, SOL_SOCKET, SO_RCVLOWAT, &r, sizeof(r)) < 0)
LogMsg("SO_RCVLOWAT IPv6 %d error %d errno %d (%s)", k->sktv6, r, errno, strerror(errno));
}
@ -2634,6 +2682,10 @@ mDNSlocal void * KQueueLoop(void *m_param)
if (end - start >= WatchDogReportingThreshold)
LogInfo("WARNING: Idle task took %dms to complete", end - start);
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
validatelists(m, true);
#endif
mDNSs32 now = mDNS_TimeNow(m);
if (m->ShutdownTime)
@ -2761,53 +2813,8 @@ mDNSlocal void * KQueueLoop(void *m_param)
mDNSlocal void LaunchdCheckin(void)
{
// Ask launchd for our socket
launch_data_t resp_sd = launch_socket_service_check_in();
if (!resp_sd)
{
LogMsg("launch_socket_service_check_in returned NULL");
return;
}
else
{
launch_data_t skts = launch_data_dict_lookup(resp_sd, LAUNCH_JOBKEY_SOCKETS);
if (!skts) LogMsg("launch_data_dict_lookup LAUNCH_JOBKEY_SOCKETS returned NULL");
else
{
launch_data_t skt = launch_data_dict_lookup(skts, "Listeners");
if (!skt) LogMsg("launch_data_dict_lookup Listeners returned NULL");
else
{
launchd_fds_count = launch_data_array_get_count(skt);
if (launchd_fds_count == 0) LogMsg("launch_data_array_get_count(skt) returned 0");
else
{
launchd_fds = mallocL("LaunchdCheckin", sizeof(dnssd_sock_t) * launchd_fds_count);
if (!launchd_fds) LogMsg("LaunchdCheckin: malloc failed");
else
{
size_t i;
for(i = 0; i < launchd_fds_count; i++)
{
launch_data_t s = launch_data_array_get_index(skt, i);
if (!s)
{
launchd_fds[i] = dnssd_InvalidSocket;
LogMsg("launch_data_array_get_index(skt, %d) returned NULL", i);
}
else
{
launchd_fds[i] = launch_data_get_fd(s);
LogInfo("Launchd Unix Domain Socket [%d]: %d", i, launchd_fds[i]);
}
}
}
// In some early versions of 10.4.x, the permissions on the UDS were not set correctly, so we fix them here
chmod(MDNS_UDS_SERVERPATH, S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | S_IROTH|S_IWOTH);
}
}
}
}
launch_data_free(resp_sd);
int result = launch_activate_socket("Listeners", &launchd_fds, &launchd_fds_count);
if (result != 0) { LogMsg("launch_activate_socket() failed errno %d (%s)", errno, strerror(errno)); }
}
static mach_port_t RegisterMachService(const char *service_name)
@ -2838,19 +2845,22 @@ mDNSexport int main(int argc, char **argv)
int i;
kern_return_t status;
log_client = asl_open(NULL, "mDNSResponder", 0);
log_msg = asl_new(ASL_TYPE_MSG);
mDNSMacOSXSystemBuildNumber(NULL);
LogMsg("%s starting %s %d", mDNSResponderVersionString, OSXVers ? "OSXVers" : "iOSVers", OSXVers ? OSXVers : iOSVers);
#if 0
LogMsg("CacheRecord %d", sizeof(CacheRecord));
LogMsg("CacheGroup %d", sizeof(CacheGroup));
LogMsg("ResourceRecord %d", sizeof(ResourceRecord));
LogMsg("RData_small %d", sizeof(RData_small));
LogMsg("CacheRecord %5d", sizeof(CacheRecord));
LogMsg("CacheGroup %5d", sizeof(CacheGroup));
LogMsg("ResourceRecord %5d", sizeof(ResourceRecord));
LogMsg("RData_small %5d", sizeof(RData_small));
LogMsg("sizeof(CacheEntity) %d", sizeof(CacheEntity));
LogMsg("RR_CACHE_SIZE %d", RR_CACHE_SIZE);
LogMsg("block usage %d", sizeof(CacheEntity) * RR_CACHE_SIZE);
LogMsg("block wastage %d", 16*1024 - sizeof(CacheEntity) * RR_CACHE_SIZE);
LogMsg("sizeof(CacheEntity) %5d", sizeof(CacheEntity));
LogMsg("RR_CACHE_SIZE %5d", RR_CACHE_SIZE);
LogMsg("block bytes used %5d", sizeof(CacheEntity) * RR_CACHE_SIZE);
LogMsg("block bytes wasted %5d", 32*1024 - sizeof(CacheEntity) * RR_CACHE_SIZE);
#endif
if (0 == geteuid())
@ -2874,8 +2884,76 @@ mDNSexport int main(int argc, char **argv)
if (!strcasecmp(argv[i], "-AlwaysAppendSearchDomains")) AlwaysAppendSearchDomains = mDNStrue;
}
#if APPLE_OSX_mDNSResponder && !TARGET_OS_EMBEDDED
/* Reads the external user's program arguments for mDNSResponder starting 10.11.x(El Capitan) on OSX. The options for external user are:
DebugLogging, UnicastPacketLogging, NoMulticastAdvertisements, StrictUnicastOrdering and AlwaysAppendSearchDomains
To turn ON the particular option, here is what the user should do (as an example of setting two options)
1] sudo defaults write /Library/Preferences/com.apple.mDNSResponder.plist AlwaysAppendSearchDomains -bool YES
2] sudo defaults write /Library/Preferences/com.apple.mDNSResponder.plist NoMulticastAdvertisements -bool YES
3] sudo reboot
To turn OFF all options, here is what the user should do
1] sudo defaults delete /Library/Preferences/com.apple.mDNSResponder.plist
2] sudo reboot
To view the current options set, here is what the user should do
1] plutil -p /Library/Preferences/com.apple.mDNSResponder.plist
OR
1] sudo defaults read /Library/Preferences/com.apple.mDNSResponder.plist
*/
CFBooleanRef enabled = NULL;
enabled = CFPreferencesCopyValue(kDebugLogging, kProgramArguments, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
if (enabled != NULL)
{
if ((CFGetTypeID(enabled) == CFBooleanGetTypeID()) && CFBooleanGetValue(enabled))
mDNS_LoggingEnabled = mDNStrue;
CFRelease(enabled);
}
enabled = CFPreferencesCopyValue(kUnicastPacketLogging, kProgramArguments, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
if (enabled != NULL)
{
if ((CFGetTypeID(enabled) == CFBooleanGetTypeID()) && CFBooleanGetValue(enabled))
mDNS_PacketLoggingEnabled = mDNStrue;
CFRelease(enabled);
}
enabled = CFPreferencesCopyValue(kNoMulticastAdvertisements, kProgramArguments, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
if (enabled != NULL)
{
if ((CFGetTypeID(enabled) == CFBooleanGetTypeID()) && CFBooleanGetValue(enabled))
advertise = mDNS_Init_DontAdvertiseLocalAddresses;
CFRelease(enabled);
}
enabled = CFPreferencesCopyValue(kStrictUnicastOrdering, kProgramArguments, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
if (enabled != NULL)
{
if ((CFGetTypeID(enabled) == CFBooleanGetTypeID()) && CFBooleanGetValue(enabled))
StrictUnicastOrdering = mDNStrue;
CFRelease(enabled);
}
enabled = CFPreferencesCopyValue(kAlwaysAppendSearchDomains, kProgramArguments, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
if (enabled != NULL)
{
if ((CFGetTypeID(enabled) == CFBooleanGetTypeID()) && CFBooleanGetValue(enabled))
AlwaysAppendSearchDomains = mDNStrue;
CFRelease(enabled);
}
#endif
// Note that mDNSPlatformInit will set DivertMulticastAdvertisements in the mDNS structure
if (!advertise) LogMsg("Administratively prohibiting multicast advertisements");
if (!advertise)
LogMsg("-NoMulticastAdvertisements is set: Administratively prohibiting multicast advertisements");
if (AlwaysAppendSearchDomains)
LogMsg("-AlwaysAppendSearchDomains is set");
if (StrictUnicastOrdering)
LogMsg("-StrictUnicastOrdering is set");
#ifndef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
@ -2886,7 +2964,6 @@ mDNSexport int main(int argc, char **argv)
signal(SIGINFO, HandleSIG); // (Debugging) Write state snapshot to syslog
signal(SIGUSR1, HandleSIG); // (Debugging) Enable Logging
signal(SIGUSR2, HandleSIG); // (Debugging) Enable Packet Logging
signal(SIGURG, HandleSIG); // (Debugging) Toggle Opportunistic Caching
signal(SIGPROF, HandleSIG); // (Debugging) Toggle Multicast Logging
signal(SIGTSTP, HandleSIG); // (Debugging) Disable all Debug Logging (USR1/USR2/PROF)
@ -2931,6 +3008,8 @@ mDNSexport int main(int argc, char **argv)
char *sandbox_msg;
uint64_t sandbox_flags = SANDBOX_NAMED;
(void)confstr(_CS_DARWIN_USER_CACHE_DIR, NULL, 0);
int sandbox_err = sandbox_init("mDNSResponder", sandbox_flags, &sandbox_msg);
if (sandbox_err)
{
@ -2945,13 +3024,6 @@ mDNSexport int main(int argc, char **argv)
}
#endif // MDNS_NO_SANDBOX
// We use BeginTransactionAtShutdown in the plist that ensures that we will
// receive a SIGTERM during shutdown rather than a SIGKILL. But launchd (due to some
// limitation) currently requires us to still start and end the transaction for
// its proper initialization.
vproc_transaction_t vt = vproc_transaction_begin(NULL);
if (vt) vproc_transaction_end(NULL, vt);
m_port = RegisterMachService(kmDNSResponderServName);
// We should ALWAYS receive our Mach port from RegisterMachService() but sanity check before initializing daemon
if (m_port == MACH_PORT_NULL)
@ -2960,15 +3032,17 @@ mDNSexport int main(int argc, char **argv)
return -1;
}
#if TARGET_OS_EMBEDDED
status = MetricsInit();
if (status) { LogMsg("Daemon start: MetricsInit failed (%d)", status); }
#endif
status = mDNSDaemonInitialize();
if (status) { LogMsg("Daemon start: mDNSDaemonInitialize failed"); goto exit; }
status = udsserver_init(launchd_fds, launchd_fds_count);
if (status) { LogMsg("Daemon start: udsserver_init failed"); goto exit; }
log_client = asl_open(NULL, "mDNSResponder", 0);
log_msg = asl_new(ASL_TYPE_MSG);
#if TARGET_OS_EMBEDDED
_scprefs_observer_watch(scprefs_observer_type_global, kmDNSResponderPrefIDStr, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2007 Apple Inc. All rights reserved.
* Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2007 Apple Inc. All rights reserved.
* Copyright (c) 2007-2012 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -39,7 +39,6 @@
#include "helper-server.h"
#include "helpermsg.h"
#include "helpermsgServer.h"
#include <vproc.h>
#if TARGET_OS_EMBEDDED
#define NO_SECURITYFRAMEWORK 1
@ -104,7 +103,7 @@ static void handle_sigterm(int sig)
static void initialize_logging(void)
{
logclient = asl_open(NULL, kmDNSHelperServiceName, (opt_debug ? ASL_OPT_STDERR : 0));
logclient = asl_open(NULL, "mDNSResponderHelper", (opt_debug ? ASL_OPT_STDERR : 0));
if (NULL == logclient) { fprintf(stderr, "Could not initialize ASL logging.\n"); fflush(stderr); return; }
if (opt_debug) asl_set_filter(logclient, ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));
}
@ -124,9 +123,10 @@ static void initialize_id(void)
static void diediedie(CFRunLoopTimerRef timer, void *context)
{
debug("entry %p %p %d", timer, context, maxidle);
debug("entry %p %p %d", timer, context, actualidle);
assert(gTimer == timer);
if (maxidle)
helplog(ASL_LEVEL_INFO, "mDNSResponder exiting after %d seconds", actualidle);
if (actualidle)
(void)proxy_mDNSExit(gPort);
}
@ -228,6 +228,8 @@ int main(int ac, char *av[])
}
ac -= optind;
av += optind;
(void)ac; // Unused
(void)av; // Unused
initialize_logging();
helplog(ASL_LEVEL_INFO, "Starting");
@ -246,13 +248,6 @@ int main(int ac, char *av[])
signal(SIGTERM, handle_sigterm);
// We use BeginTransactionAtShutdown in the plist that ensures that we will
// receive a SIGTERM during shutdown rather than a SIGKILL. But launchd (due to some
// limitation) currently requires us to still start and end the transaction for
// its proper initialization.
vproc_transaction_t vt = vproc_transaction_begin(NULL);
if (vt) vproc_transaction_end(NULL, vt);
if (initialize_timer()) exit(EXIT_FAILURE);
for (n=0; n<100000; n++) if (!gRunLoop) usleep(100);
if (!gRunLoop)

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2007 Apple Inc. All rights reserved.
* Copyright (c) 2007-2011 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007-2012 Apple Inc. All rights reserved.
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2007-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -169,26 +170,28 @@ void mDNSNotify(const char *title, const char *msg) // Both strings are UTF-8 te
if (title)
{
// Dont try to call mDNSPlatformMem* routines here, because they call validatelists,
// which calls back into mDNSNotify, resulting an infinite loop until stack space is exhausted
int len = strlen(title);
titleCopy = mDNSPlatformMemAllocate(len + 1);
titleCopy = malloc(len + 1);
if (!titleCopy)
{
LogMsg("mDNSNotify: titleCopy NULL for %s", msg);
return;
}
mDNSPlatformMemCopy(titleCopy, title, len);
memcpy(titleCopy, title, len);
titleCopy[len] = 0;
}
if (msg)
{
int len = strlen(msg);
msgCopy = mDNSPlatformMemAllocate(len + 1);
msgCopy = malloc(len + 1);
if (!msgCopy)
{
LogMsg("mDNSNotify: msgCopy NULL for %s", msg);
return;
}
mDNSPlatformMemCopy(msgCopy, msg, len);
memcpy(msgCopy, msg, len);
msgCopy[len] = 0;
}
@ -203,10 +206,10 @@ void mDNSNotify(const char *title, const char *msg) // Both strings are UTF-8 te
kr = proxy_mDNSNotify(getHelperPort(retry), titleCopy, msgCopy);
MACHRETRYLOOP_END(kr, retry, err, fin);
fin:
if (titleCopy)
mDNSPlatformMemFree(titleCopy);
if (msgCopy)
mDNSPlatformMemFree(msgCopy);
// Dont try to call mDNSPlatformMem* routines here, because they call validatelists,
// which calls back into mDNSNotify, resulting an infinite loop until stack space is exhausted
free(titleCopy);
free(msgCopy);
(void)err;
});
}
@ -231,7 +234,7 @@ int mDNSKeychainGetSecrets(CFArrayRef *result)
LogMsg("%s: CFDataCreateWithBytesNoCopy failed", __func__);
goto fin;
}
if (NULL == (plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, bytes, kCFPropertyListImmutable, NULL)))
if (NULL == (plist = CFPropertyListCreateWithData(kCFAllocatorDefault, bytes, kCFPropertyListImmutable, NULL, NULL)))
{
err = kmDNSHelperInvalidPList;
LogMsg("%s: CFPropertyListCreateFromXMLData failed", __func__);
@ -456,7 +459,7 @@ void mDNSGetRemoteMAC(mDNS *const m, int family, v6addr_t raddr)
// the values and schedule a task to update the MAC address in the TCP Keepalive record.
if (kr == KERN_SUCCESS)
{
addrMapping = (IPAddressMACMapping *)malloc(sizeof(IPAddressMACMapping));
addrMapping = mDNSPlatformMemAllocate(sizeof(IPAddressMACMapping));
snprintf(addrMapping->ethaddr, sizeof(addrMapping->ethaddr), "%02x:%02x:%02x:%02x:%02x:%02x",
eth[0], eth[1], eth[2], eth[3], eth[4], eth[5]);
if (family == AF_INET)

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2007-2012 Apple Inc. All rights reserved.
* Copyright (c) 2007-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -61,6 +61,8 @@
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <IOKit/pwr_mgt/IOPMLibPrivate.h>
#ifndef RTF_IFSCOPE
#define RTF_IFSCOPE 0x1000000
#endif
@ -183,13 +185,24 @@ kern_return_t do_mDNSPowerRequest(__unused mach_port_t port, int key, int interv
}
else if (key > 0)
{
CFDateRef w = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent() + interval);
if (w)
CFDateRef wakeTime = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent() + interval);
if (wakeTime)
{
IOReturn r = IOPMSchedulePowerEvent(w, CFSTR("mDNSResponderHelper"), key ? CFSTR(kIOPMAutoWake) : CFSTR(kIOPMAutoSleep));
if (r) { usleep(100000); helplog(ASL_LEVEL_ERR, "IOPMSchedulePowerEvent(%d) %d %x", interval, r, r); }
CFMutableDictionaryRef scheduleDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(scheduleDict, CFSTR(kIOPMPowerEventTimeKey), wakeTime);
CFDictionaryAddValue(scheduleDict, CFSTR(kIOPMPowerEventAppNameKey), CFSTR("mDNSResponderHelper"));
CFDictionaryAddValue(scheduleDict, CFSTR(kIOPMPowerEventTypeKey), key ? CFSTR(kIOPMAutoWake) : CFSTR(kIOPMAutoSleep));
IOReturn r = IOPMRequestSysWake(scheduleDict);
if (r)
{
usleep(100000);
helplog(ASL_LEVEL_ERR, "IOPMRequestSysWake(%d) %d %x", interval, r, r);
}
*err = r;
CFRelease(w);
CFRelease(wakeTime);
CFRelease(scheduleDict);
}
}
fin:
@ -332,7 +345,8 @@ kern_return_t do_mDNSNotify(__unused mach_port_t port, const char *title, const
if (!authorized(&token)) return KERN_SUCCESS;
#ifndef NO_CFUSERNOTIFICATION
static const char footer[] = "(Note: This message only appears on machines with 17.x.x.x IP addresses — i.e. at Apple — not on customer machines.)";
static const char footer[] = "(Note: This message only appears on machines with 17.x.x.x IP addresses"
" or on debugging builds with ForceAlerts set — i.e. only at Apple — not on customer machines.)";
CFStringRef alertHeader = CFStringCreateWithCString(NULL, title, kCFStringEncodingUTF8);
CFStringRef alertBody = CFStringCreateWithCString(NULL, msg, kCFStringEncodingUTF8);
CFStringRef alertFooter = CFStringCreateWithCString(NULL, footer, kCFStringEncodingUTF8);
@ -429,7 +443,7 @@ static void ShowNameConflictNotification(CFMutableArrayRef header, CFStringRef s
CFRelease(dictionary);
}
static CFMutableArrayRef GetHeader(const char* oldname, const char* newname, const CFStringRef msg, const char* suffix)
static CFMutableArrayRef CreateAlertHeader(const char* oldname, const char* newname, const CFStringRef msg, const char* suffix)
{
CFMutableArrayRef alertHeader = NULL;
@ -464,7 +478,8 @@ static CFMutableArrayRef GetHeader(const char* oldname, const char* newname, con
CFStringRef userName = SCDynamicStoreCopyConsoleUser(NULL, &uid, &gid);
if (userName)
{
CFRelease(userName);
if (!CFEqual(userName, CFSTR("_mbsetupuser")))
{
CFArrayAppendValue(alertHeader, msg); // Opening phrase of message, provided by caller
CFArrayAppendValue(alertHeader, CFS_OQ); CFArrayAppendValue(alertHeader, s1); CFArrayAppendValue(alertHeader, CFS_CQ);
CFArrayAppendValue(alertHeader, CFSTR(" is already in use on this network. "));
@ -477,6 +492,8 @@ static CFMutableArrayRef GetHeader(const char* oldname, const char* newname, con
else
CFArrayAppendValue(alertHeader, CFSTR("All attempts to find an available name by adding a number to the name were also unsuccessful."));
}
CFRelease(userName);
}
}
if (s1) CFRelease(s1);
if (s2) CFRelease(s2);
@ -494,16 +511,20 @@ static void update_notification(void)
debug("entry ucn=%s, uhn=%s, lcn=%s, lhn=%s", usercompname, userhostname, lastcompname, lasthostname);
if (!CFS_OQ)
{
// Note: the "\xEF\xBB\xBF" byte sequence in the CFS_Format string is the UTF-8 encoding of the zero-width non-breaking space character.
// Note: The "\xEF\xBB\xBF" byte sequence (U+FEFF) in the CFS_Format string is the UTF-8 encoding of the zero-width non-breaking space character.
// By appending this invisible character on the end of literal names, we ensure the these strings cannot inadvertently match any string
// in the localization file -- since we know for sure that none of our strings in the localization file contain the ZWNBS character.
//
// For languages that are written right to left, when we mix English (host names could be in english with brackets etc. and the
// rest in Arabic) we need unicode markups for proper formatting. The Unicode sequence 202C (UTF8 E2 80 AC), 200E (UTF8 E2 80 8E) and
// 202B (UTF8 E2 80 AB) helps with the formatting. See <rdar://problem/8629082> for more details.
CFS_OQ = CFStringCreateWithCString(NULL, "\xE2\x80\xAB", kCFStringEncodingUTF8);
CFS_CQ = CFStringCreateWithCString(NULL, "\xE2\x80\xAC", kCFStringEncodingUTF8);
CFS_Format = CFStringCreateWithCString(NULL, "%@%s\xEF\xBB\xBF\xE2\x80\x8E", kCFStringEncodingUTF8);
CFS_Format = CFStringCreateWithCString(NULL, "%@%s\xEF\xBB\xBF", kCFStringEncodingUTF8);
// The strings CFS_OQ, CFS_CQ and the others below are the localization keys for the “Localizable.strings” files,
// and MUST NOT BE CHANGED, or localization substitution will be broken.
// To change the text displayed to the user, edit the values in the appropriate “Localizable.strings” file, not the keys here.
// This includes making changes for adding appropriate directionality overrides like LRM, LRE, RLE, PDF, etc. These need to go in the values
// in the appropriate “Localizable.strings” entries, not in the keys here (which then wont match *any* entry in the localization files).
// These localization keys here were broken in <rdar://problem/8629082> and then subsequently repaired in
// <rdar://problem/21071535> [mDNSResponder]: TA: Gala15A185: Incorrect punctuation marks when Change the host name to an exist one
CFS_OQ = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8); // DO NOT CHANGE THIS STRING
CFS_CQ = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8); // DO NOT CHANGE THIS STRING
CFS_ComputerName = CFStringCreateWithCString(NULL, "The name of your computer ", kCFStringEncodingUTF8);
CFS_ComputerNameMsg = CFStringCreateWithCString(NULL, "To change the name of your computer, "
"open System Preferences and click Sharing, then type the name in the Computer Name field.", kCFStringEncodingUTF8);
@ -529,17 +550,17 @@ static void update_notification(void)
CFStringRef* subtext = NULL;
if (userhostname[0] && !lasthostname[0]) // we've given up trying to construct a name that doesn't conflict
{
header = GetHeader(userhostname, NULL, CFS_LocalHostName, ".local");
header = CreateAlertHeader(userhostname, NULL, CFS_LocalHostName, ".local");
subtext = &CFS_Problem;
}
else if (usercompname[0])
{
header = GetHeader(usercompname, lastcompname, CFS_ComputerName, "");
header = CreateAlertHeader(usercompname, lastcompname, CFS_ComputerName, "");
subtext = &CFS_ComputerNameMsg;
}
else
{
header = GetHeader(userhostname, lasthostname, CFS_LocalHostName, ".local");
header = CreateAlertHeader(userhostname, lasthostname, CFS_LocalHostName, ".local");
subtext = &CFS_LocalHostNameMsg;
}
ShowNameConflictNotification(header, *subtext);
@ -912,6 +933,8 @@ do_mDNSKeychainGetSecrets(__unused mach_port_t port, __unused unsigned int *nums
*err = kmDNSHelperKeychainCopyDefaultFailed;
goto fin;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if (noErr != (status = SecKeychainSearchCreateFromAttributes(skc, kSecGenericPasswordItemClass, NULL, &search)))
{
*err = kmDNSHelperKeychainSearchCreationFailed;
@ -932,6 +955,7 @@ do_mDNSKeychainGetSecrets(__unused mach_port_t port, __unused unsigned int *nums
SecKeychainItemFreeAttributesAndData(attributes, NULL);
CFRelease(item);
}
#pragma clang diagnostic pop
if (errSecItemNotFound != status)
helplog(ASL_LEVEL_ERR, "%s: SecKeychainSearchCopyNext failed: %d",
__func__, status);
@ -944,8 +968,8 @@ do_mDNSKeychainGetSecrets(__unused mach_port_t port, __unused unsigned int *nums
goto fin;
}
CFWriteStreamOpen(stream);
if (0 == CFPropertyListWriteToStream(keys, stream,
kCFPropertyListBinaryFormat_v1_0, NULL))
if (0 == CFPropertyListWrite(keys, stream,
kCFPropertyListBinaryFormat_v1_0, 0, NULL))
{
*err = kmDNSHelperPListWriteFailed;
debug("CFPropertyListWriteToStream failed");
@ -1022,6 +1046,11 @@ CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
// Major version 8 is 10.4.x (Tiger)
// Major version 9 is 10.5.x (Leopard)
// Major version 10 is 10.6.x (SnowLeopard)
// Major version 11 is 10.7.x (Lion)
// Major version 12 is 10.8.x (MountainLion)
// Major version 13 is 10.9.x (Mavericks)
// Major version 14 is 10.10.x (Yosemite)
// Major version 15 is 10.11.x (ElCapitan)
static int MacOSXSystemBuildNumber(char* letter_out, int* minor_out)
{
int major = 0, minor = 0;
@ -2332,13 +2361,15 @@ in_cksum(unsigned short *ptr,int nbytes)
* all the carry bits from the top 16 bits into the lower 16 bits.
*/
sum = 0;
while (nbytes > 1) {
while (nbytes > 1)
{
sum += *ptr++;
nbytes -= 2;
}
/* mop up an odd byte, if necessary */
if (nbytes == 1) {
if (nbytes == 1)
{
/* make sure top half is zero */
oddbyte = 0;
@ -2726,20 +2757,42 @@ static int getMACAddress(int family, v6addr_t raddr, v6addr_t gaddr, int *gfamil
sin6 = (struct sockaddr_in6 *) (rtm +1);
sdl = (struct sockaddr_dl *) (sin6->sin6_len + (char *) sin6);
}
if (!sdl)
{
helplog(ASL_LEVEL_ERR, "do_mDNSGetRemoteMAC: sdl is NULL for family %d", family);
close(sock);
return -1;
}
// If the address is not on the local net, we get the IP address of the gateway.
// We would have to repeat the process to get the MAC address of the gateway
*gfamily = sdl->sdl_family;
if (sdl->sdl_family == AF_INET)
{
if (sin)
{
struct sockaddr_in *new_sin = (struct sockaddr_in *)(sin->sin_len +(char*) sin);
memcpy(gaddr, &new_sin->sin_addr, sizeof(struct in_addr));
}
else
{
helplog(ASL_LEVEL_ERR, "do_mDNSGetRemoteMAC: sin is NULL");
}
close(sock);
return -1;
}
else if (sdl->sdl_family == AF_INET6)
{
if (sin6)
{
struct sockaddr_in6 *new_sin6 = (struct sockaddr_in6 *)(sin6->sin6_len +(char*) sin6);
memcpy(gaddr, &new_sin6->sin6_addr, sizeof(struct in6_addr));
}
else
{
helplog(ASL_LEVEL_ERR, "do_mDNSGetRemoteMAC: sin6 is NULL");
}
close(sock);
return -1;
}

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2007-2012 Apple Inc. All rights reserved.
* Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2007 Apple Inc. All rights reserved.
* Copyright (c) 2007-2011 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2007-2012 Apple Inc. All rights reserved.
* Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2003-2007 Apple Computer, Inc. All rights reserved.
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2003-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $FreeBSD: src/lib/libipsec/ipsec_strerror.h,v 1.1.2.2 2001/07/03 11:01:14 ume Exp $ */
/* $KAME: ipsec_strerror.h,v 1.8 2000/07/30 00:45:12 itojun Exp $ */

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2003-2007 Apple Computer, Inc. All rights reserved.
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2003-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $FreeBSD: src/lib/libipsec/libpfkey.h,v 1.1.2.2 2001/07/03 11:01:14 ume Exp $ */
/* $KAME: libpfkey.h,v 1.6 2001/03/05 18:22:17 thorpej Exp $ */

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -51,10 +51,6 @@ extern mDNSBool GetmDNSManagedPref(CFStringRef key);
#include <Security/Security.h>
#endif /* NO_SECURITYFRAMEWORK */
#if TARGET_OS_IPHONE
#include "cellular_usage_policy.h"
#endif
#define kmDNSResponderServName "com.apple.mDNSResponder"
enum mDNSDynamicStoreSetConfigKey
@ -141,8 +137,6 @@ struct NetworkInterfaceInfoOSX_struct
mDNSu8 Occulting; // Set if interface vanished for less than 60 seconds and then came back
mDNSu8 D2DInterface; // IFEF_LOCALNET_PRIVATE flag indicates we should call
// D2D plugin for operations over this interface
mDNSu8 DirectLink; // IFEF_DIRECTLINK flag is set for interface
mDNSs32 AppearanceTime; // Time this interface appeared most recently in getifaddrs list
// i.e. the first time an interface is seen, AppearanceTime is set.
// If an interface goes away temporarily and then comes back then
@ -181,7 +175,6 @@ struct mDNS_PlatformSupport_struct
domainlabel prevnewnicelabel; // Previous m->nicelabel
mDNSs32 NotifyUser;
mDNSs32 HostNameConflict; // Time we experienced conflict on our link-local host name
mDNSs32 NetworkChanged;
mDNSs32 KeyChainTimer;
CFRunLoopRef CFRunLoop;
@ -216,9 +209,6 @@ struct mDNS_PlatformSupport_struct
TCPSocket TCPProxy;
ProxyCallback *UDPProxyCallback;
ProxyCallback *TCPProxyCallback;
#if TARGET_OS_IPHONE
cellular_usage_policy_client_t handle;
#endif
};
extern int OfferSleepProxyService;

View File

@ -8,8 +8,6 @@
<true/>
<key>com.apple.private.network.socket-delegate</key>
<true/>
<key>com.apple.networkd.cellular_blocked.notify</key>
<true/>
<key>com.apple.private.SCNetworkConnection-proxy-user</key>
<true/>
<key>com.apple.private.network.reserved-port</key>
@ -18,8 +16,6 @@
<true/>
<key>com.apple.private.snhelper</key>
<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>

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
; -*- Mode: Scheme; tab-width: 4 -*-
;
; Copyright (c) 2012 Apple Inc. All rights reserved.
; Copyright (c) 2012-2015 Apple Inc. All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
@ -10,7 +10,7 @@
; 2. Redistributions in binary form must reproduce the above copyright notice,
; this list of conditions and the following disclaimer in the documentation
; and/or other materials provided with the distribution.
; 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
; 3. Neither the name of Apple Inc. ("Apple") nor the names of its
; contributors may be used to endorse or promote products derived from this
; software without specific prior written permission.
;
@ -45,9 +45,12 @@
; Mach communications
; These are needed for things like getpwnam, hostname changes, & keychain
(allow mach-lookup
(global-name "com.apple.awdd")
(global-name "com.apple.bsd.dirhelper")
(global-name "com.apple.CoreServices.coreservicesd")
(global-name "com.apple.coreservices.quarantine-resolver")
(global-name "com.apple.distributed_notifications.2")
(global-name "com.apple.lsd.mapdb")
(global-name "com.apple.ocspd")
(global-name "com.apple.PowerManagement.control")
(global-name "com.apple.mDNSResponderHelper")
@ -58,13 +61,13 @@
(global-name "com.apple.SystemConfiguration.NetworkInformation")
(global-name "com.apple.system.notification_center")
(global-name "com.apple.system.logger")
(global-name "com.apple.usymptomsd")
(global-name "com.apple.webcontentfilter.dns")
(global-name "com.apple.server.bluetooth")
(global-name "com.apple.awacs")
(global-name "com.apple.networkd")
(global-name "com.apple.securityd")
(global-name "com.apple.wifi.manager")
(global-name "com.apple.commcenter.cupolicy.xpc")
(global-name "com.apple.blued")
(global-name "com.apple.mobilegestalt.xpc")
(global-name "com.apple.snhelper"))
@ -99,6 +102,7 @@
(literal "/usr/sbin")
(literal "/usr/sbin/mDNSResponder")
(literal "/Library/Preferences/com.apple.mDNSResponder.plist")
(literal "/Library/Preferences/SystemConfiguration/preferences.plist")
(literal "/Library/Preferences/SystemConfiguration/com.apple.nat.plist")
(regex #"^/Library/Preferences/(ByHost/)?\.GlobalPreferences\.")
@ -136,10 +140,7 @@
(regex #"^/private/var/folders/[^/]+/[^/]+/C/mds(/|$)")
; Required on 10.5 and 10.6
(regex #"^/private/var/folders/[^/]+/[^/]+/-Caches-/mds(/|$)")
; Required on 10.10.4
(regex #"^/private/var/folders/[^/]+/[^/]+/[0-9]+(/|$)"))
(regex #"^/private/var/folders/[^/]+/[^/]+/-Caches-/mds(/|$)"))
; CRL Cache for SSL/TLS connections
(allow file-read-data (literal "/private/var/db/crls/crlcache.db"))

View File

@ -1,6 +1,6 @@
.\" -*- tab-width: 4 -*-
.\"
.\" Copyright (c) 2007 Apple Computer, Inc. All Rights Reserved.
.\" Copyright (c) 2007-2009 Apple Inc. All Rights Reserved.
.\"
.\" Licensed under the Apache License, Version 2.0 (the "License");
.\" you may not use this file except in compliance with the License.

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2003-2007 Apple Computer, Inc. All rights reserved.
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2003-2011 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $FreeBSD: src/lib/libipsec/pfkey.c,v 1.1.2.2 2001/07/03 11:01:14 ume Exp $ */
/* $KAME: pfkey.c,v 1.39 2001/03/05 18:22:17 thorpej Exp $ */

View File

@ -0,0 +1,155 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2013, 2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mDNSMacOSX.h"
#include <libproc.h>
#include <network/private.h>
//Gets the DNSPolicy from NW PATH EVALUATOR
mDNSexport void mDNSPlatformGetDNSRoutePolicy(mDNS *const m, DNSQuestion *q, mDNSBool *isCellBlocked)
{
(void) m;
q->ServiceID = -1; // initialize the ServiceID to default value of -1
// Return for non-unicast DNS queries, invalid pid, if NWPathEvaluation is already done by the client, or NWPathEvaluation not available on this OS
if (mDNSOpaque16IsZero(q->TargetQID) || (q->pid < 0) || (q->flags & kDNSServiceFlagsPathEvaluationDone) || !nw_endpoint_create_host)
{
*isCellBlocked = mDNSfalse;
return;
}
mDNSs32 service_id;
mDNSu32 client_ifindex, dnspol_ifindex;
int retval;
struct proc_uniqidentifierinfo info;
mDNSBool isUUIDSet;
char unenc_name[MAX_ESCAPED_DOMAIN_NAME];
ConvertDomainNameToCString(&q->qname, unenc_name);
nw_endpoint_t host = nw_endpoint_create_host(unenc_name, "0");
if (host == NULL)
LogMsg("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] nw_endpoint_t host is NULL", q->qname.c,
DNSTypeName(q->qtype), q->pid, q->euid, q->ServiceID);
nw_parameters_t parameters = nw_parameters_create();
if (parameters == NULL)
LogMsg("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] nw_endpoint_t parameters is NULL", q->qname.c,
DNSTypeName(q->qtype), q->pid, q->euid, q->ServiceID);
// Check for all the special (negative) internal value interface indices before initializing client_ifindex
if ( (q->InterfaceID == mDNSInterface_Any)
|| (q->InterfaceID == mDNSInterface_Unicast)
|| (q->InterfaceID == mDNSInterface_LocalOnly)
|| (q->InterfaceID == mDNSInterfaceMark)
|| (q->InterfaceID == mDNSInterface_P2P)
|| (q->InterfaceID == uDNSInterfaceMark))
{
client_ifindex = 0;
}
else
{
client_ifindex = (mDNSu32)(uintptr_t)q->InterfaceID;
}
if (client_ifindex > 0)
{
nw_interface_t client_intf = nw_interface_create_with_index(client_ifindex);
nw_parameters_require_interface(parameters, client_intf);
if (client_intf != NULL)
network_release(client_intf);
else
LogInfo("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy: client_intf returned by nw_interface_create_with_index() is NULL");
}
nw_parameters_set_uid(parameters,(uid_t)q->euid);
if (q->pid != 0)
{
nw_parameters_set_pid(parameters, q->pid);
retval = proc_pidinfo(q->pid, PROC_PIDUNIQIDENTIFIERINFO, 1, &info, sizeof(info));
if (retval == (int)sizeof(info))
{
nw_parameters_set_e_proc_uuid(parameters, info.p_uuid);
isUUIDSet = mDNStrue;
}
else
{
debugf("mDNSPlatformGetDNSRoutePolicy: proc_pidinfo returned %d", retval);
isUUIDSet = mDNSfalse;
}
}
else
{
nw_parameters_set_e_proc_uuid(parameters, q->uuid);
isUUIDSet = mDNStrue;
}
nw_path_evaluator_t evaluator = nw_path_create_evaluator_for_endpoint(host, parameters);
if (evaluator == NULL)
LogMsg("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] nw_path_evaluator_t evaluator is NULL", q->qname.c,
DNSTypeName(q->qtype), q->pid, q->euid, q->ServiceID);
if (host != NULL)
network_release(host);
if (parameters != NULL)
network_release(parameters);
nw_path_t path = nw_path_evaluator_copy_path(evaluator);
if (path == NULL)
LogMsg("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] nw_path_t path is NULL", q->qname.c,
DNSTypeName(q->qtype), q->pid, q->euid, q->ServiceID);
service_id = nw_path_get_flow_divert_unit(path);
if (service_id != 0)
{
q->ServiceID = service_id;
LogInfo("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy: Query for %##s service ID is set ->service_ID:[%d] ", q->qname.c, service_id);
}
else
{
nw_interface_t nwpath_intf = nw_path_copy_scoped_interface(path);
if (nwpath_intf != NULL)
{
// Use the new scoped interface given by NW PATH EVALUATOR
dnspol_ifindex = nw_interface_get_index(nwpath_intf);
q->InterfaceID = (mDNSInterfaceID)(uintptr_t)dnspol_ifindex;
network_release(nwpath_intf);
if (dnspol_ifindex != client_ifindex)
LogInfo("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy has changed the scoped ifindex from [%d] to [%d]",
client_ifindex, dnspol_ifindex);
}
else
{
debugf("mDNSPlatformGetDNSRoutePolicy: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] nw_interface_t nwpath_intf is NULL ", q->qname.c, DNSTypeName(q->qtype), q->pid, q->euid, q->ServiceID);
}
}
if (isUUIDSet && TARGET_OS_IPHONE && nw_path_get_status(path) == nw_path_status_unsatisfied && nw_path_get_reason(path) == nw_path_reason_policy_drop)
*isCellBlocked = mDNStrue;
else
*isCellBlocked = mDNSfalse;
if (path != NULL)
network_release(path);
if (evaluator != NULL)
network_release(evaluator);
}

Binary file not shown.

View File

@ -330,8 +330,10 @@ mDNSexport int main(int argc, char **argv)
if (StopNow == 2) break;
}
#endif
else {
if (strlen(arg) >= sizeof(hostname)) {
else
{
if (strlen(arg) >= sizeof(hostname))
{
fprintf(stderr, "hostname must be < %d characters\n", (int)sizeof(hostname));
goto usage;
}

View File

@ -153,6 +153,7 @@ LINKOPTS = -lSystem
LDSUFFIX = dylib
JDK = /System/Library/Frameworks/JavaVM.framework/Home
JAVACFLAGS_OS = -dynamiclib -I/System/Library/Frameworks/JavaVM.framework/Headers -framework JavaVM
OPTIONALTARG = dnsextd
else
$(error ERROR: Must specify target OS on command-line, e.g. "make os=x [target]".\
@ -215,7 +216,7 @@ CFLAGS = $(CFLAGS_COMMON) $(CFLAGS_OS) $(CFLAGS_DEBUG)
#############################################################################
all: setup Daemon libdns_sd Clients SAClient SAResponder SAProxyResponder Identify NetMonitor dnsextd $(OPTIONALTARG)
all: setup Daemon libdns_sd Clients SAClient SAResponder SAProxyResponder Identify NetMonitor $(OPTIONALTARG)
install: setup InstalledDaemon InstalledStartup InstalledLib InstalledManPages InstalledClients $(OPTINSTALL)

View File

@ -308,6 +308,20 @@ CVE-ID
CVE-2011-0220 : JaeSeung Song of the Department of Computing at Imperial
College London
Impact:  A local application may be able to cause a denial of service
Description:  A denial of service issue was addressed through
improved memory handling.
CVE-ID
CVE-2015-7988 : Alexandre Helie
Impact:  A remote attacker may be able to cause unexpected
application termination or arbitrary code execution
Description:  Multiple memory corruption issues existed in DNS
data parsing. These issues were addressed through improved bounds
checking.
CVE-ID
CVE-2015-7987 : Alexandre Helie
To Do List
----------
• port to a System V that's not Solaris

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2002-2015 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -525,6 +525,7 @@ mDNSexport int ParseDNSServers(mDNS *m, const char *filePath)
numOfServers++;
}
}
fclose(fp);
return (numOfServers > 0) ? 0 : -1;
}
@ -648,10 +649,22 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
// ... with a shared UDP port, if it's for multicast receiving
if (err == 0 && port.NotAnInteger)
{
#if defined(SO_REUSEPORT)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
#elif defined(SO_REUSEADDR)
// <rdar://problem/20946253>
// We test for SO_REUSEADDR first, as suggested by Jonny Törnbom from Axis Communications
// Linux kernel versions 3.9 introduces support for socket option
// SO_REUSEPORT, however this is not implemented the same as on *BSD
// systems. Linux version implements a "port hijacking" prevention
// mechanism, limiting processes wanting to bind to an already existing
// addr:port to have the same effective UID as the first who bound it. What
// this meant for us was that the daemon ran as one user and when for
// instance mDNSClientPosix was executed by another user, it wasn't allowed
// to bind to the socket. Our suggestion was to switch the order in which
// SO_REUSEPORT and SO_REUSEADDR was tested so that SO_REUSEADDR stays on
// top and SO_REUSEPORT to be used only if SO_REUSEADDR doesn't exist.
#if defined(SO_REUSEADDR) && !defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
#elif defined(SO_REUSEPORT)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
#else
#error This platform has no way to avoid address busy errors on multicast.
#endif
@ -919,6 +932,7 @@ mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct
if (strcmp(intfName, STRINGIFY(DIRECTLINK_INTERFACE_NAME)) == 0)
intf->coreIntf.DirectLink = mDNStrue;
#endif
intf->coreIntf.SupportsUnicastMDNSResponse = mDNStrue;
// The interface is all ready to go, let's register it with the mDNS core.
if (err == 0)
@ -1625,21 +1639,15 @@ mDNSexport mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID)
return mDNSfalse;
}
mDNSexport mDNSBool mDNSPlatformAllowPID(mDNS *const m, DNSQuestion *q)
mDNSexport void mDNSPlatformGetDNSRoutePolicy(mDNS *const m, DNSQuestion *q, mDNSBool *isCellBlocked)
{
(void) m;
(void) q;
return mDNStrue;
q->ServiceID = -1;
*isCellBlocked = mDNSfalse;
}
mDNSexport mDNSs32 mDNSPlatformGetServiceID(mDNS *const m, DNSQuestion *q)
{
(void) m;
(void) q;
return -1;
}
mDNSexport void mDNSPlatformSetDelegatePID(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q)
mDNSexport void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q)
{
(void) src;
(void) dst;

View File

@ -83,14 +83,12 @@ void plen_to_mask(int plen, char *addr) {
struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
{
struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
FILE *fp;
FILE *fp = NULL;
char addr[8][5];
int flags, myflags, index, plen, scope;
char ifname[9], lastname[IFNAMSIZ];
char addr6[32+7+1]; /* don't forget the seven ':' */
struct addrinfo hints, *res0;
struct sockaddr_in6 *sin6;
struct in6_addr *addrptr;
int err;
int sockfd = -1;
struct ifreq ifr;
@ -150,18 +148,13 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
char ipv6addr[INET6_ADDRSTRLEN];
plen_to_mask(plen, ipv6addr);
ifi->ifi_netmask = calloc(1, sizeof(struct sockaddr_in6));
if (ifi->ifi_addr == NULL) {
if (ifi->ifi_netmask == NULL) {
goto gotError;
}
sin6=calloc(1, sizeof(struct sockaddr_in6));
addrptr=calloc(1, sizeof(struct in6_addr));
inet_pton(family, ipv6addr, addrptr);
sin6->sin6_family=family;
sin6->sin6_addr=*addrptr;
sin6->sin6_scope_id=scope;
memcpy(ifi->ifi_netmask, sin6, sizeof(struct sockaddr_in6));
free(sin6);
((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_family=family;
((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_scope_id=scope;
inet_pton(family, ipv6addr, &((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_addr);
/* Add interface name */
memcpy(ifi->ifi_name, ifname, IFI_NAME);
@ -179,6 +172,7 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
* EADDRNOTAVAIL for the main interface
*/
free(ifi->ifi_addr);
free(ifi->ifi_netmask);
free(ifi);
ifipnext = ifiptr;
*ifipnext = ifipold;
@ -207,6 +201,9 @@ done:
if (sockfd != -1) {
assert(close(sockfd) == 0);
}
if (fp != NULL) {
fclose(fp);
}
return(ifihead); /* pointer to first structure in linked list */
}
#endif // defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX

View File

@ -36,7 +36,7 @@ if [ -r /sbin/start-stop-daemon ]; then
# Suse Linux doesn't work with symbolic signal names, but we really don't need
# to specify "-s TERM" since SIGTERM (15) is the default stop signal anway
# STOP="start-stop-daemon --stop -s TERM --quiet --oknodo --exec"
STOP="start-stop-daemon --stop --quiet --oknodo --exec"
STOP="start-stop-daemon --stop --quiet --oknodo --retry 2 --exec"
else
killmdnsd() {
kill -TERM `cat /var/run/mdnsd.pid`

Some files were not shown because too many files have changed in this diff Show More