version 320.10
diff --git a/Makefile b/Makefile
index 501abbe..75a0f57 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@
include /Developer/Makefiles/pb_makefiles/platform.make
-MVERS = "mDNSResponder-320.5.1"
+MVERS = "mDNSResponder-320.10"
DDNSWRITECONFIG = "$(DSTROOT)/Library/Application Support/Bonjour/ddnswriteconfig"
diff --git a/mDNSCore/DNSCommon.c b/mDNSCore/DNSCommon.c
index 2c23925..b75c128 100644
--- a/mDNSCore/DNSCommon.c
+++ b/mDNSCore/DNSCommon.c
@@ -1369,12 +1369,20 @@
return(rr->namehash == q->qnamehash && SameDomainName(rr->name, &q->qname));
}
-// This is called only when the caller knows that it is a Unicast Resource Record and it is a Unicast Question
-// and hence we don't need InterfaceID checks like above. Though this may not be a big optimization, the main
-// reason we need this is that we can't compare DNSServers between the question and the resource record because
-// the resource record may not be completely initialized e.g., mDNSCoreReceiveResponse
-mDNSexport mDNSBool UnicastResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q)
+// This is called with both unicast resource record and multicast resource record. The question that
+// received the unicast response could be the regular unicast response from a DNS server or a response
+// to a mDNS QU query. The main reason we need this function is that we can't compare DNSServers between the
+// question and the resource record because the resource record is not completely initialized in
+// mDNSCoreReceiveResponse when this function is called.
+mDNSexport mDNSBool ResourceRecordAnswersUnicastResponse(const ResourceRecord *const rr, const DNSQuestion *const q)
{
+ // For resource records created using multicast, the InterfaceIDs have to match
+ if (rr->InterfaceID &&
+ q->InterfaceID && rr->InterfaceID != q->InterfaceID) return(mDNSfalse);
+
+ // If ResourceRecord received via multicast, but question was unicast, then shouldn't use record to answer this question.
+ if (rr->InterfaceID && !mDNSOpaque16IsZero(q->TargetQID)) return(mDNSfalse);
+
// RR type CNAME matches any query type. QTYPE ANY matches any RR type. QCLASS ANY matches any RR class.
if (!RRTypeAnswersQuestionType(rr,q->qtype)) return(mDNSfalse);
diff --git a/mDNSCore/DNSCommon.h b/mDNSCore/DNSCommon.h
index 08c636d..5df4ce4 100644
--- a/mDNSCore/DNSCommon.h
+++ b/mDNSCore/DNSCommon.h
@@ -164,7 +164,7 @@
extern mDNSBool SameNameRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
extern mDNSBool ResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
extern mDNSBool AnyTypeRecordAnswersQuestion (const ResourceRecord *const rr, const DNSQuestion *const q);
-extern mDNSBool UnicastResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
+extern mDNSBool ResourceRecordAnswersUnicastResponse(const ResourceRecord *const rr, const DNSQuestion *const q);
extern mDNSBool LocalOnlyRecordAnswersQuestion(AuthRecord *const rr, const DNSQuestion *const q);
extern mDNSu16 GetRDLength(const ResourceRecord *const rr, mDNSBool estimate);
extern mDNSBool ValidateRData(const mDNSu16 rrtype, const mDNSu16 rdlength, const RData *const rd);
diff --git a/mDNSCore/mDNS.c b/mDNSCore/mDNS.c
index 005983c..ede13e9 100755
--- a/mDNSCore/mDNS.c
+++ b/mDNSCore/mDNS.c
@@ -349,7 +349,7 @@
if (addr->type == mDNSAddrType_IPv6)
{
- if (mDNSv6AddressIsLinkLocal(&addr->ip.v4)) return(mDNStrue);
+ if (mDNSv6AddressIsLinkLocal(&addr->ip.v6)) return(mDNStrue);
for (intf = m->HostInterfaces; intf; intf = intf->next)
if (intf->ip.type == addr->type && intf->InterfaceID == InterfaceID && intf->McastTxRx)
if ((((intf->ip.ip.v6.l[0] ^ addr->ip.v6.l[0]) & intf->mask.ip.v6.l[0]) == 0) &&
@@ -1663,6 +1663,7 @@
AuthRecord *rr;
AuthRecord *ResponseRecords = mDNSNULL;
AuthRecord **nrp = &ResponseRecords;
+ NetworkInterfaceInfo *intf = FirstInterfaceForID(m, InterfaceID);
// Make a list of all our records that need to be unicast to this destination
for (rr = m->ResourceRecords; rr; rr=rr->next)
@@ -1674,6 +1675,7 @@
rr->ImmedUnicast = mDNSfalse;
if (rr->ImmedUnicast && rr->ImmedAnswer == InterfaceID)
+ {
if ((dest->type == mDNSAddrType_IPv4 && mDNSSameIPv4Address(rr->v4Requester, dest->ip.v4)) ||
(dest->type == mDNSAddrType_IPv6 && mDNSSameIPv6Address(rr->v6Requester, dest->ip.v6)))
{
@@ -1681,9 +1683,18 @@
rr->ImmedUnicast = mDNSfalse;
rr->v4Requester = zerov4Addr;
rr->v6Requester = zerov6Addr;
+
+ // Only sent records registered for P2P over P2P interfaces
+ if (intf && !mDNSPlatformValidRecordForInterface(rr, intf))
+ {
+ LogInfo("SendDelayedUnicastResponse: Not sending %s, on %s", ARDisplayString(m, rr), InterfaceNameForID(m, InterfaceID));
+ continue;
+ }
+
if (rr->NextResponse == mDNSNULL && nrp != &rr->NextResponse) // rr->NR_AnswerTo
{ rr->NR_AnswerTo = (mDNSu8*)~0; *nrp = rr; nrp = &rr->NextResponse; }
}
+ }
}
AddAdditionalsToResponseList(m, ResponseRecords, &nrp, InterfaceID);
@@ -1730,7 +1741,7 @@
}
if (m->omsg.h.numAnswers)
- mDNSSendDNSMessage(m, &m->omsg, responseptr, mDNSInterface_Any, mDNSNULL, dest, MulticastDNSPort, mDNSNULL, mDNSNULL);
+ mDNSSendDNSMessage(m, &m->omsg, responseptr, InterfaceID, mDNSNULL, dest, MulticastDNSPort, mDNSNULL, mDNSNULL);
}
}
@@ -2240,7 +2251,7 @@
if ((rr->SendRNow == intf->InterfaceID) &&
((rr->resrec.InterfaceID == mDNSInterface_Any) && !mDNSPlatformValidRecordForInterface(rr, intf)))
{
- LogInfo("SendResponses: Not Sending %s, on %s", ARDisplayString(m, rr), InterfaceNameForID(m, rr->SendRNow));
+ LogInfo("SendResponses: Not sending %s, on %s", ARDisplayString(m, rr), InterfaceNameForID(m, rr->SendRNow));
rr->SendRNow = GetNextActiveInterfaceID(intf);
}
else if (rr->SendRNow == intf->InterfaceID)
@@ -6278,6 +6289,8 @@
return(mDNSNULL);
}
+// This function is called when we receive a unicast response. This could be the case of a unicast response from the
+// DNS server or a response to the QU query. Hence, the cache record's InterfaceId can be both NULL or non-NULL (QU case)
mDNSlocal DNSQuestion *ExpectingUnicastResponseForRecord(mDNS *const m,
const mDNSAddr *const srcaddr, const mDNSBool SrcLocal, const mDNSIPPort port, const mDNSOpaque16 id, const CacheRecord *const rr, mDNSBool tcp)
{
@@ -6285,12 +6298,9 @@
(void)id;
(void)srcaddr;
- // Unicast records have zero as InterfaceID
- if (rr->resrec.InterfaceID) return mDNSNULL;
-
for (q = m->Questions; q; q=q->next)
{
- if (!q->DuplicateOf && UnicastResourceRecordAnswersQuestion(&rr->resrec, q))
+ if (!q->DuplicateOf && ResourceRecordAnswersUnicastResponse(&rr->resrec, q))
{
if (!mDNSOpaque16IsZero(q->TargetQID))
{
diff --git a/mDNSCore/uDNS.c b/mDNSCore/uDNS.c
index 513150b..47559a4 100755
--- a/mDNSCore/uDNS.c
+++ b/mDNSCore/uDNS.c
@@ -3156,7 +3156,7 @@
rr->updateError = err;
#if APPLE_OSX_mDNSResponder
- if (err == mStatus_BadSig) UpdateAutoTunnelDomainStatuses(m);
+ if (err == mStatus_BadSig || err == mStatus_BadKey) UpdateAutoTunnelDomainStatuses(m);
#endif
SetRecordRetry(m, rr, random);
diff --git a/mDNSMacOSX/mDNSMacOSX.c b/mDNSMacOSX/mDNSMacOSX.c
index f782826..1ee1c1f 100644
--- a/mDNSMacOSX/mDNSMacOSX.c
+++ b/mDNSMacOSX/mDNSMacOSX.c
@@ -3170,7 +3170,7 @@
for (ptr = m->AuthInfoList; ptr; ptr = ptr->next)
if (SameDomainName(&ptr->domain, n))
{
- if (ptr == info && r->updateError == mStatus_BadSig)
+ if (ptr == info && (r->updateError == mStatus_BadSig || r->updateError == mStatus_BadKey))
{
mDNS_snprintf(buffer, bufsz, "Resource record update failed for %##s", r->resrec.name);
return r->updateError;
@@ -7616,6 +7616,8 @@
// "hash" function to solve this, the others are hard to solve. Hence, we share the hash (AuthHash) implementation
// of the core layer which does all of the above very efficiently
+#define ETCHOSTS_BUFSIZE 1024 // Buffer size to parse a single line in /etc/hosts
+
mDNSexport void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result)
{
(void)m; // unused
@@ -7757,6 +7759,8 @@
*name = NULL;
for (i = start; i < length; i++)
{
+ if (buffer[i] == '#')
+ return -1;
if (buffer[i] != ' ' && buffer[i] != ',' && buffer[i] != '\t')
{
*name = &buffer[i];
@@ -7935,58 +7939,38 @@
mDNSlocal void mDNSMacOSXParseEtcHosts(mDNS *const m, int fd, AuthHash *auth)
{
- if (fd == -1) { LogInfo("mDNSMacOSXParseEtcHosts: fd is -1"); return; }
-
- LogInfo("mDNSMacOSXParseEtcHosts: Parsing etc hosts");
+ mDNSBool good;
+ char buf[ETCHOSTS_BUFSIZE];
+ int len;
+ FILE *fp;
- // Read through the file
- char readBuf[1024]; // support a maximum line of 1024 bytes including newline
- off_t offset = 0;
- int comment = 0;
- ssize_t i = 0;
- ssize_t length;
- ssize_t linestart;
- while ((length = pread(fd, &readBuf[i], sizeof(readBuf) - i, offset) + i) >= i)
+ if (fd == -1) { LogInfo("mDNSMacOSXParseEtcHosts: fd is -1"); return; }
+
+ fp = fopen("/etc/hosts", "r");
+ if (!fp) { LogInfo("mDNSMacOSXParseEtcHosts: fp is NULL"); return; }
+
+ while (1)
{
- if (length == i)
- {
- // end of file
- if (length != 0) mDNSMacOSXParseEtcHostsLine(m, readBuf, length, auth);
- break;
- }
-
- // increment our offset by the number of bytes we read
- offset += length - i;
-
- // loop through the buffer looking for end of lines
- for (linestart = 0; i < length; i++)
- {
- if (readBuf[i] == '#' || readBuf[i] == '\r' || readBuf[i] == '\n')
- {
- int parseline = i - linestart > 0 && comment == 0;
- comment = readBuf[i] == '#';
- if (parseline)
- {
- readBuf[i] = 0;
- mDNSMacOSXParseEtcHostsLine(m, &readBuf[linestart], i - linestart, auth);
- }
- linestart = i + 1;
- }
- }
-
- // prepare to read the next chunk of the file
- if (linestart == 0)
- {
- // single line was larger than our buffer, we're going to ignore it
- comment = 1; // treat remainder of line as comment
- i = 0;
- }
- else
- {
- i = length - linestart;
- if (i) memmove(readBuf, &readBuf[linestart], i);
- }
+ good = (fgets(buf, ETCHOSTS_BUFSIZE, fp) != NULL);
+ if (!good) break;
+
+ // skip comment and empty lines
+ if (buf[0] == '#' || buf[0] == '\r' || buf[0] == '\n')
+ continue;
+
+ len = strlen(buf);
+ if (!len) break; // sanity check
+
+ if (buf[len - 1] == '\r' || buf[len - 1] == '\n')
+ buf[len - 1] = '\0';
+
+ // fgets always null terminates and hence even if we have no
+ // newline at the end, it is null terminated. The callee expects
+ // the length to be such that buf[length] to be zero and hence
+ // we pass len - 1.
+ mDNSMacOSXParseEtcHostsLine(m, buf, len - 1, auth);
}
+ fclose(fp);
}
mDNSlocal void mDNSMacOSXUpdateEtcHosts(mDNS *const m);
diff --git a/mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj b/mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj
index d03b50d..3362c8a 100644
--- a/mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj
+++ b/mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj
@@ -274,10 +274,10 @@
fileType = sourcecode.yacc;
isEditable = 1;
outputFiles = (
- "$(DERIVED_FILE_DIR)/dnsextd_parser.h",
- "$(DERIVED_FILE_DIR)/dnsextd_parser.c",
+ "$(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).h",
+ "$(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).c",
);
- script = "/usr/bin/bison -o ${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}.c -d ${INPUT_FILE_PATH}";
+ script = "echo NOOP yacc ${INPUT_FILE_PATH}";
};
D284BFB80ADD8E510027CCDF /* PBXBuildRule */ = {
isa = PBXBuildRule;
@@ -285,7 +285,7 @@
fileType = sourcecode.lex;
isEditable = 1;
outputFiles = (
- "$(DERIVED_FILE_DIR)/dnsextd_lexer.c",
+ "$(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).c",
);
script = "/usr/bin/flex -i -o${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}.c ${INPUT_FILE_PATH}";
};
@@ -1337,9 +1337,9 @@
buildConfigurationList = D284BED60ADD80A20027CCDF /* Build configuration list for PBXNativeTarget "dnsextd" */;
buildPhases = (
D284BEC20ADD80A20027CCDF /* Headers */,
+ 4A4EE3A413CB8E82005C624B /* Build yacc file into derived source files */,
D284BEC40ADD80A20027CCDF /* Sources */,
D284BECE0ADD80A20027CCDF /* Frameworks */,
- D284BED30ADD80A20027CCDF /* Rez */,
D284BED40ADD80A20027CCDF /* CopyFiles */,
FFFF8F770C32F0FD00722979 /* CopyFiles */,
FF37FAAD0BC581780044A5CF /* ShellScript */,
@@ -1561,13 +1561,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- D284BED30ADD80A20027CCDF /* Rez */ = {
- isa = PBXRezBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
D284BEE40ADD80A70027CCDF /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
@@ -1637,6 +1630,23 @@
shellPath = /bin/sh;
shellScript = "#if we are building for simulator, change the installation path\nif [ \"${RC_ProjectName%_Sim}\" != \"${RC_ProjectName}\" ] ; then\n\tDSTROOT=${DSTROOT}${SDKROOT}\nfi\nmkdir -p \"$DSTROOT/usr/include/DNSServiceDiscovery\"\ncp $SRCROOT/DNSServiceDiscovery.h $DSTROOT/usr/include/DNSServiceDiscovery\nsed 's/\\(^#define _DNS_SD_LIBDISPATCH \\)0$/\\1 1/' \"$SRCROOT/../mDNSShared/dns_sd.h\" > \"$DSTROOT/usr/include/dns_sd.h\"";
};
+ 4A4EE3A413CB8E82005C624B /* Build yacc file into derived source files */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "$(SRCROOT)/../mDNSShared/dnsextd_parser.y",
+ );
+ name = "Build yacc file into derived source files";
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/dnsextd_parser.c",
+ "$(DERIVED_FILE_DIR)/dnsextd_parser.h",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/usr/bin/bison -o ${SCRIPT_OUTPUT_FILE_0} -d ${SCRIPT_INPUT_FILE_0}";
+ };
D284BE510ADD80740027CCDF /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -2421,9 +2431,6 @@
"${CONFIGURATION_TEMP_DIR}",
);
INSTALL_PATH = /usr/sbin;
- LEX = /usr/bin/flex;
- LEXFLAGS = "";
- LEX_CASE_INSENSITIVE_SCANNER = YES;
LIBRARY_SEARCH_PATHS = "\"${CONFIGURATION_TEMP_DIR}\"";
MACOSX_DEPLOYMENT_TARGET = 10.5;
OTHER_CFLAGS = (
@@ -2432,11 +2439,8 @@
);
OTHER_LDFLAGS = "";
"OTHER_LDFLAGS[sdk=macosx10.7][arch=*]" = "-Wl,-pie";
- OTHER_REZFLAGS = "";
PRODUCT_NAME = dnsextd;
- REZ_EXECUTABLE = YES;
SECTORDER_FLAGS = "";
- YACC = "/usr/bin/bison -y";
};
name = Development;
};
diff --git a/mDNSShared/dns_sd.h b/mDNSShared/dns_sd.h
index 3588d59..56c1d30 100644
--- a/mDNSShared/dns_sd.h
+++ b/mDNSShared/dns_sd.h
@@ -77,7 +77,7 @@
*/
#ifndef _DNS_SD_H
-#define _DNS_SD_H 3200501
+#define _DNS_SD_H 3201000
#ifdef __cplusplus
extern "C" {