version 258.18
diff --git a/Makefile b/Makefile
index 89f009d..18b458f 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@
 
 include /Developer/Makefiles/pb_makefiles/platform.make
 
-MVERS = "mDNSResponder-258.14"
+MVERS = "mDNSResponder-258.18"
 
 DDNSWRITECONFIG = "$(DSTROOT)/Library/Application Support/Bonjour/ddnswriteconfig"
 
diff --git a/mDNSCore/mDNS.c b/mDNSCore/mDNS.c
index 91f37de..700282e 100755
--- a/mDNSCore/mDNS.c
+++ b/mDNSCore/mDNS.c
@@ -7104,7 +7104,7 @@
 				!mDNSv6AddressIsLoopback(&i->ip.ip.v6) &&
 				!mDNSv6AddressIsLinkLocal(&i->ip.ip.v6) &&
 				!mDNSSameIPv6Address(i->ip.ip.v6, m->AutoTunnelHostAddr) &&
-				!mDNSSameIPv6Address(i->ip.ip.v6, m->AutoTunnelRelayAddr))
+				!mDNSSameIPv6Address(i->ip.ip.v6, m->AutoTunnelRelayAddrOut))
 				{
 				LogInfo("ShouldSuppressQuery: Query not suppressed for %##s, qtype %s, Local Address %.16a found", qname, DNSTypeName(qtype),
 					&i->ip.ip.v6);
@@ -9557,7 +9557,7 @@
 	m->AutoTunnelHostAddrActive = mDNSfalse;
 	m->AutoTunnelLabel.c[0]     = 0;
 
-	m->RegisterSearchDomains    = mDNSfalse;
+	m->StartWABQueries          = mDNSfalse;
 	m->RegisterAutoTunnel6      = mDNStrue;
 
 	// NAT traversal fields
@@ -9852,13 +9852,16 @@
 	
 	debugf("uDNS_SetupDNSConfig: entry");
 
-	if (m->RegisterSearchDomains) uDNS_RegisterSearchDomains(m);
+	// Let the platform layer get the current DNS information
+	// The m->StartWABQueries boolean is so that we lazily get the search domain list only on-demand
+	// and start the domain enumeration queries. (no need to hit the network with domain enumeration
+	// queries until we actually need that information).
+
+	uDNS_SetupSearchDomains(m, m->StartWABQueries ? (UDNS_START_WAB_QUERY | UDNS_START_CF_QUERY) :
+		(UDNS_START_CF_QUERY));
 
 	mDNS_Lock(m);
 
-	// Let the platform layer get the current DNS information
-	// The m->RegisterSearchDomains boolean is so that we lazily get the search domain list only on-demand
-	// (no need to hit the network with domain enumeration queries until we actually need that information).
 	for (ptr = m->DNSServers; ptr; ptr = ptr->next)
 		{
 		ptr->penaltyTime = 0;
diff --git a/mDNSCore/mDNSEmbeddedAPI.h b/mDNSCore/mDNSEmbeddedAPI.h
index 509d50b..a9881d0 100755
--- a/mDNSCore/mDNSEmbeddedAPI.h
+++ b/mDNSCore/mDNSEmbeddedAPI.h
@@ -1636,6 +1636,10 @@
 	mDNSu8          NetWake;			// Set if Wake-On-Magic-Packet is enabled on this interface
 	};
 
+#define SLE_DELETE              0x00000001
+#define SLE_WAB_QUERY_STARTED   0x00000002
+#define SLE_CF_QUERY_STARTED    0x00000004
+
 typedef struct SearchListElem
 	{
 	struct SearchListElem *next;
@@ -1646,8 +1650,8 @@
 	DNSQuestion AutomaticBrowseQ;
 	DNSQuestion RegisterQ;
 	DNSQuestion DefRegisterQ;
-	DNSQuestion DirQ;
-	int	numDirAnswers;
+	DNSQuestion CfQ;
+	int	numCfAnswers;
 	ARListElem *AuthRecs;
 	} SearchListElem;
 
@@ -1790,10 +1794,15 @@
 	HostnameInfo     *Hostnames;            // List of registered hostnames + hostname metadata
 	mDNSv6Addr        AutoTunnelHostAddr;	// IPv6 address advertised for AutoTunnel services on this machine
 	mDNSBool          AutoTunnelHostAddrActive;
-	mDNSv6Addr        AutoTunnelRelayAddr;	// IPv6 address advertised for AutoTunnel Relay services on this machine
+	// AutoTunnel Relay address has two distinct uses
+	// AutoTunnelRelayAddrIn: If non-zero, it means that this host can be reached (inbound connection) through the relay
+	// AutoTunnelRelayAddrOut: If non-zero, it means that this host can use the relay to reach (outbound connection) the
+	// other hosts through the relay
+	mDNSv6Addr        AutoTunnelRelayAddrIn;
+	mDNSv6Addr        AutoTunnelRelayAddrOut;
 	domainlabel       AutoTunnelLabel;		// Used to construct hostname for *IPv4* address of tunnel endpoints
 
-	mDNSBool          RegisterSearchDomains;
+	mDNSBool          StartWABQueries;
 	mDNSBool          RegisterAutoTunnel6;
 
 	// NAT-Traversal fields
diff --git a/mDNSCore/uDNS.c b/mDNSCore/uDNS.c
index dcfcf65..2d6ba4b 100755
--- a/mDNSCore/uDNS.c
+++ b/mDNSCore/uDNS.c
@@ -4577,8 +4577,9 @@
 	for (p = &SearchList; *p; p = &(*p)->next)
 		if (SameDomainName(&(*p)->domain, domain))
 			{
-			// If domain is already in list, and marked for deletion, change it to "leave alone"
-			if ((*p)->flag == -1) (*p)->flag = 0;
+			// If domain is already in list, and marked for deletion, unmark the delete
+			// Be careful not to touch the other flags that may be present
+			if ((*p)->flag & SLE_DELETE) (*p)->flag &= ~SLE_DELETE;
 			LogInfo("mDNS_AddSearchDomain already in list %##s", domain->c);
 			return;
 			}
@@ -4588,7 +4589,6 @@
 	if (!*p) { LogMsg("ERROR: mDNS_AddSearchDomain - malloc"); return; }
 	mDNSPlatformMemZero(*p, sizeof(SearchListElem));
 	AssignDomainName(&(*p)->domain, domain);
-	(*p)->flag = 1;	// add
 	(*p)->next = mDNSNULL;
 	LogInfo("mDNS_AddSearchDomain created new %##s", domain->c);
 	}
@@ -4630,40 +4630,40 @@
 	}
 #endif
 
-mDNSlocal void FoundDirDomain(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
+mDNSlocal void FoundCFDomain(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
 	{
 	SearchListElem *slElem = question->QuestionContext;
 	mDNSBool RegisterAutoTunnel6 = mDNStrue;
 	char *res = "DisableInboundRelay";
 	
-	LogInfo("FoundDirDomain: InterfaceID %p %s Question %##s Answer %s", answer->InterfaceID, AddRecord ? "Add" : "Rmv", question->qname.c, RRDisplayString(m, answer));
+	LogInfo("FoundCFDomain: InterfaceID %p %s Question %##s Answer %s", answer->InterfaceID, AddRecord ? "Add" : "Rmv", question->qname.c, RRDisplayString(m, answer));
 	if (answer->rrtype != kDNSType_TXT)
 		{
-		LogMsg("FoundDirDomain: answer type is not TXT %s for question %##s", DNSTypeName(answer->rrtype), question->qname.c);
+		LogMsg("FoundCFDomain: answer type is not TXT %s for question %##s", DNSTypeName(answer->rrtype), question->qname.c);
 		return;
 		}
 	if (answer->RecordType == kDNSRecordTypePacketNegative)
 		{
-		LogInfo("FoundDirDomain: Negative answer for %##s", question->qname.c);
+		LogInfo("FoundCFDomain: Negative answer for %##s", question->qname.c);
 		return;
 		}
 	if (answer->InterfaceID == mDNSInterface_LocalOnly)
 		{
-		LogInfo("FoundDirDomain: LocalOnly interfaceID for %##s", question->qname.c);
+		LogInfo("FoundCFDomain: LocalOnly interfaceID for %##s", question->qname.c);
 		return;
 		}
 
 	// TXT record is encoded as <len><data>
 	if (answer->rdlength != mDNSPlatformStrLen(res) + 1)
 		{
-		LogInfo("FoundDirDomain: Invalid TXT record to disable %##s, length %d", question->qname.c, answer->rdlength);
+		LogInfo("FoundCFDomain: Invalid TXT record to disable %##s, length %d", question->qname.c, answer->rdlength);
 		return;
 		}
 
 	// Compare the data (excluding the len byte)
 	if (!mDNSPlatformMemSame(&answer->rdata->u.txt.c[1], res, answer->rdlength - 1))
 		{
-		LogInfo("FoundDirDomain: Invalid TXT record to disable %##s", question->qname.c);
+		LogInfo("FoundCFDomain: Invalid TXT record to disable %##s", question->qname.c);
 		return;
 		}
 
@@ -4671,17 +4671,17 @@
 	// have zero answers across all domains to register autotunnel6.
 	if (AddRecord)
 		{
-		slElem->numDirAnswers++;
+		slElem->numCfAnswers++;
 		RegisterAutoTunnel6 = mDNSfalse;
 		}
 	else
 		{
 		const SearchListElem *s;
-		slElem->numDirAnswers--;
-		if (slElem->numDirAnswers < 0) LogMsg("FoundDirDomain: numDirAnswers less than zero %d", slElem->numDirAnswers);
+		slElem->numCfAnswers--;
+		if (slElem->numCfAnswers < 0) LogMsg("FoundCFDomain: numCfAnswers less than zero %d", slElem->numCfAnswers);
 		// See if any domain (including the slElem) has any answers
  		for (s=SearchList; s; s=s->next)
-			if (s->numDirAnswers) { RegisterAutoTunnel6 = mDNSfalse; break; }
+			if (s->numCfAnswers) { RegisterAutoTunnel6 = mDNSfalse; break; }
 		}
 #if APPLE_OSX_mDNSResponder
 	CheckAutoTunnel6Registration(m, RegisterAutoTunnel6);
@@ -4773,7 +4773,7 @@
 	}
 #endif
 
-mDNSlocal void mDNS_StartDirQuestion(mDNS *const m, DNSQuestion *question, domainname *domain, void *context)
+mDNSlocal void mDNS_StartCFQuestion(mDNS *const m, DNSQuestion *question, domainname *domain, void *context)
 	{
 	AssignDomainName (&question->qname, (const domainname*)"\002cf" "\007_dns-sd" "\x04_udp");
 	AppendDomainName (&question->qname, domain);
@@ -4786,55 +4786,62 @@
 	question->ForceMCast       = mDNSfalse;
 	question->ReturnIntermed   = mDNSfalse;
 	question->SuppressUnusable = mDNSfalse;
-	question->QuestionCallback = FoundDirDomain;
+	question->QuestionCallback = FoundCFDomain;
 	question->QuestionContext  = context;
-	LogInfo("mDNS_StartDirQuestion: Start DIR domain question %##s", question->qname.c);
+	LogInfo("mDNS_StartCFQuestion: Start CF domain question %##s", question->qname.c);
 	if (mDNS_StartQuery(m, question))
-		LogMsg("mDNS_StartDirQuestion: ERROR!! cannot start _dir._dns-sd query");
+		LogMsg("mDNS_StartCFQuestion: ERROR!! cannot start cf._dns-sd query");
 	}
 
 // This should probably move to the UDS daemon -- the concept of legacy clients and automatic registration / automatic browsing
 // is really a UDS API issue, not something intrinsic to uDNS
-mDNSexport mStatus uDNS_RegisterSearchDomains(mDNS *const m)
+mDNSexport mStatus uDNS_SetupSearchDomains(mDNS *const m, int action)
 	{
 	SearchListElem **p = &SearchList, *ptr;
 	const SearchListElem *s;
 	mDNSBool RegisterAutoTunnel6 = mDNStrue;
 	mStatus err;
 
-	// step 1: mark each element for removal (-1)
-	for (ptr = SearchList; ptr; ptr = ptr->next) ptr->flag = -1;
+	// step 1: mark each element for removal
+	for (ptr = SearchList; ptr; ptr = ptr->next) ptr->flag |= SLE_DELETE;
 
 	// Client has requested domain enumeration or automatic browse -- time to make sure we have the search domains from the platform layer
 	mDNS_Lock(m);
-	m->RegisterSearchDomains = mDNStrue;
-	mDNSPlatformSetDNSConfig(m, mDNSfalse, m->RegisterSearchDomains, mDNSNULL, mDNSNULL, mDNSNULL);
+	mDNSPlatformSetDNSConfig(m, mDNSfalse, mDNStrue, mDNSNULL, mDNSNULL, mDNSNULL);
 	mDNS_Unlock(m);
 
+	if (action & UDNS_START_WAB_QUERY)
+		m->StartWABQueries = mDNStrue;
+
 	// delete elems marked for removal, do queries for elems marked add
 	while (*p)
 		{
 		ptr = *p;
-		LogInfo("RegisterSearchDomains %d %p %##s", ptr->flag, ptr->AuthRecs, ptr->domain.c);
-		if (ptr->flag == -1)	// remove
+		LogInfo("uDNS_SetupSearchDomains:action %d: Flags %d,  AuthRecs %p, %##s", action, ptr->flag, ptr->AuthRecs, ptr->domain.c);
+		if (ptr->flag & SLE_DELETE)
 			{
 			ARListElem *arList = ptr->AuthRecs;
 			ptr->AuthRecs = mDNSNULL;
 			*p = ptr->next;
 
 			// If the user has "local" in their DNS searchlist, we ignore that for the purposes of domain enumeration queries
-			// Note: Stopping a question will not generate the RMV events for the question (handled in FoundDirDomain)
+			// Note: Stopping a question will not generate the RMV events for the question (handled in FoundCFDomain)
 			// and hence we need to recheck all the domains to see if we need to register/deregister _autotunnel6.
 			// This is done at the end.
-			if (!SameDomainName(&ptr->domain, &localdomain))
+			if ((ptr->flag & SLE_WAB_QUERY_STARTED) && !SameDomainName(&ptr->domain, &localdomain))
 				{
 				mDNS_StopGetDomains(m, &ptr->BrowseQ);
 				mDNS_StopGetDomains(m, &ptr->RegisterQ);
 				mDNS_StopGetDomains(m, &ptr->DefBrowseQ);
 				mDNS_StopGetDomains(m, &ptr->DefRegisterQ);
 				mDNS_StopGetDomains(m, &ptr->AutomaticBrowseQ);
-				mDNS_StopGetDomains(m, &ptr->DirQ);
 				}
+#if !TARGET_OS_EMBEDDED
+			if ((ptr->flag & SLE_CF_QUERY_STARTED) && !SameDomainName(&ptr->domain, &localdomain))
+				{
+				mDNS_StopGetDomains(m, &ptr->CfQ);
+				}
+#endif
 			mDNSPlatformMemFree(ptr);
 
 	        // deregister records generated from answers to the query
@@ -4844,15 +4851,15 @@
 				arList = arList->next;
 				debugf("Deregistering PTR %##s -> %##s", dereg->ar.resrec.name->c, dereg->ar.resrec.rdata->u.name.c);
 				err = mDNS_Deregister(m, &dereg->ar);
-				if (err) LogMsg("uDNS_RegisterSearchDomains ERROR!! mDNS_Deregister returned %d", err);
+				if (err) LogMsg("uDNS_SetupSearchDomains:: ERROR!! mDNS_Deregister returned %d", err);
 				// Memory will be freed in the FreeARElemCallback
 				}
 			continue;
 			}
 
-		if (ptr->flag == 1)	// add
+		if ((action & UDNS_START_WAB_QUERY) && !(ptr->flag & SLE_WAB_QUERY_STARTED))
 			{
-			// If the user has "local" in their DNS searchlist, we ignore that for the purposes of domain enumeration queries
+			// If the user has "local" in their DNS searchlist, we ignore that for the purposes of domain enumeration queries.
 			if (!SameDomainName(&ptr->domain, &localdomain))
 				{
 				mStatus err1, err2, err3, err4, err5;
@@ -4862,28 +4869,37 @@
 				err4 = mDNS_GetDomains(m, &ptr->DefRegisterQ,     mDNS_DomainTypeRegistrationDefault, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
 				err5 = mDNS_GetDomains(m, &ptr->AutomaticBrowseQ, mDNS_DomainTypeBrowseAutomatic,     &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
 				if (err1 || err2 || err3 || err4 || err5)
-					LogMsg("uDNS_RegisterSearchDomains: GetDomains for domain %##s returned error(s):\n"
+					LogMsg("uDNS_SetupSearchDomains: GetDomains for domain %##s returned error(s):\n"
 						   "%d (mDNS_DomainTypeBrowse)\n"
 						   "%d (mDNS_DomainTypeBrowseDefault)\n"
 						   "%d (mDNS_DomainTypeRegistration)\n"
 						   "%d (mDNS_DomainTypeRegistrationDefault)"
 						   "%d (mDNS_DomainTypeBrowseAutomatic)\n",
 						   ptr->domain.c, err1, err2, err3, err4, err5);
-				mDNS_StartDirQuestion(m, &ptr->DirQ, &ptr->domain, ptr);
+				ptr->flag |= SLE_WAB_QUERY_STARTED;
 				}
-			ptr->flag = 0;
 			}
-
-		if (ptr->flag) { LogMsg("uDNS_RegisterSearchDomains - unknown flag %d. Skipping.", ptr->flag); }
+#if !TARGET_OS_EMBEDDED
+		if ((action & UDNS_START_CF_QUERY) && !(ptr->flag & SLE_CF_QUERY_STARTED))
+			{
+			if (!SameDomainName(&ptr->domain, &localdomain))
+				{
+				mDNS_StartCFQuestion(m, &ptr->CfQ, &ptr->domain, ptr);
+				ptr->flag |= SLE_CF_QUERY_STARTED;
+				}
+			}
+#endif
 
 		p = &ptr->next;
 		}
+#if !TARGET_OS_EMBEDDED
 	// if there is any domain has answers, need to deregister autotunnel6
  	for (s=SearchList; s; s=s->next)
-		if (s->numDirAnswers) { RegisterAutoTunnel6 = mDNSfalse; break; }
+		if (s->numCfAnswers) { RegisterAutoTunnel6 = mDNSfalse; break; }
 #if APPLE_OSX_mDNSResponder
 	CheckAutoTunnel6Registration(m, RegisterAutoTunnel6);
 #endif
+#endif
 	return mStatus_NoError;
 	}
 
diff --git a/mDNSCore/uDNS.h b/mDNSCore/uDNS.h
index 0562dae..a06b9ae 100755
--- a/mDNSCore/uDNS.h
+++ b/mDNSCore/uDNS.h
@@ -91,7 +91,17 @@
 extern void CheckNATMappings(mDNS *m);
 
 extern mStatus         uDNS_SetupDNSConfig(mDNS *const m);
-extern mStatus         uDNS_RegisterSearchDomains(mDNS *const m);
+
+// uDNS_SetupSearchDomains by default adds search domains. It also can be called with one or
+// more values for "action" which does the following:
+//
+// -UDNS_START_WAB_QUERY - start Wide Area Bonjour (domain enumeration) queries
+// -UDNS_START_CF_QUERY - start Configuration query
+
+#define UDNS_START_WAB_QUERY    0x00000001
+#define UDNS_START_CF_QUERY     0x00000002
+
+extern mStatus         uDNS_SetupSearchDomains(mDNS *const m, int action);
 
 typedef enum
 	{
diff --git a/mDNSMacOSX/mDNSMacOSX.c b/mDNSMacOSX/mDNSMacOSX.c
index 6b59caa..19f5d0a 100644
--- a/mDNSMacOSX/mDNSMacOSX.c
+++ b/mDNSMacOSX/mDNSMacOSX.c
@@ -48,7 +48,6 @@
 #include "dns_sd.h"					// For mDNSInterface_LocalOnly etc.
 #include "PlatformCommon.h"
 #include "uds_daemon.h"
-#include <CoreServices/CoreServices.h>
 
 #include <stdio.h>
 #include <stdarg.h>                 // For va_list support
@@ -3057,725 +3056,6 @@
 
 static DomainAuthInfo* AnonymousRacoonConfig = mDNSNULL;
 
-// We arbitrarily limit the message size to 128 bytes (which seems sufficient now) so that
-// freeing ELogContext is simpler which is treated as opaque quantity in many places
-typedef struct
-	{
-	char subdomain[32];
-	char message[128];
-	uuid_t uuid;
-	int result;
-	} ELogContext;
-
-typedef enum { HTTPGet = 1, HTTPPost } HTTPOperation;
-typedef enum { ConfigInvalid = 0, ConfigFetching, ConfigValid } ConfigState;
-typedef void (*HTTPClientCallback)(CFMutableDataRef responseData, ELogContext *context);
-#define	kReadStreamBufferSize			4096
-#define	kMaximumResponseSize			32768
-#define	kHTTPResponseCodeOK				200
-#define	kHTTPResponseCodeAuthFailure	401
-#define	kHTTPResponseCodeForbidden		403
-#define	kHTTPResponseCodeNotFound		404
-
-// eReporter configuration needs to be fetched whenever it becomes stale. We fetch it lazily
-// when we send the report.
-struct eReporterConfiguration {
-	CFDictionaryRef eRDict;
-	ConfigState eRState;
-} eReporterConfig;
-
-typedef struct
-	{
-	mDNSBool				authChecked;
-	CFHTTPAuthenticationRef	authentication;
-	CFMutableDataRef		responseData;
-	HTTPClientCallback		callback;
-	ELogContext				cbcontext;
-	HTTPOperation 			op;
-	CFStringRef 			headerFieldName;
-	CFStringRef 			headerFieldValue;
-	CFDataRef 				bodyData;
-	CFStringRef				url;
-	} HTTPDataStreamContext;
-
-
-// Forward declarations
-mDNSlocal void HTTPDataStream(CFStringRef url, HTTPOperation op, CFDataRef bodyData, CFStringRef headerFieldName,
-	CFStringRef headerFieldValue, CFHTTPAuthenticationRef auth, CFMutableDictionaryRef credentials,
-	HTTPClientCallback callback, ELogContext *context);
-mDNSlocal void mDNSReporterLogValidConfig(ELogContext *elog);
-
-mDNSlocal void CancelReadStream(CFReadStreamRef readStream)
-	{
-	if (readStream)
-		{
-		CFReadStreamSetClient(readStream, kCFStreamEventNone, NULL, NULL);
-		CFReadStreamUnscheduleFromRunLoop(readStream, CFRunLoopGetMain(), kCFRunLoopCommonModes);
-		CFReadStreamClose(readStream);
-		CFRelease(readStream);
-		}
-	}
-
-mDNSlocal void CancelHTTPDataStream(CFReadStreamRef stream, HTTPDataStreamContext *context)
-	{
-	LogInfo("CancelHTTPDataStream: called");
-	if (context)
-		{
-		if (context->authentication) CFRelease(context->authentication);
-		if (context->responseData) CFRelease(context->responseData);
-		if (context->headerFieldName) CFRelease(context->headerFieldName);
-		if (context->headerFieldValue) CFRelease(context->headerFieldValue);
-		if (context->bodyData) CFRelease(context->bodyData);
-		if (context->url) CFRelease(context->url);
-		freeL("HTTPDataStreamContext", context);
-		}
-	CancelReadStream(stream);
-	}
-
-mDNSlocal CFIndex HTTPResponseCode(CFReadStreamRef stream)
-	{
-	CFIndex errorCode = 0;
-	CFHTTPMessageRef responseHeaders = (CFHTTPMessageRef)CFReadStreamCopyProperty(stream, kCFStreamPropertyHTTPResponseHeader);
-	if (responseHeaders)
-		{
-		errorCode = CFHTTPMessageGetResponseStatusCode(responseHeaders);
-		CFRelease(responseHeaders);
-		}
-	return errorCode;
-	}
-
-mDNSlocal void RetryWithHTTPAuth(HTTPDataStreamContext *context, CFReadStreamRef stream)
-	{
-    CFStreamError err;
-	DomainAuthInfo *FoundInList;
-	CFMutableDictionaryRef	credentials = NULL;
-
-	// Need to use the same authentication object till it goes invalid
-	if (!context->authentication)
-		{
-		CFHTTPMessageRef responseHeader = (CFHTTPMessageRef)CFReadStreamCopyProperty(stream, kCFStreamPropertyHTTPResponseHeader);
-		// Get the authentication information from the response.
-		context->authentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader);
-		CFRelease(responseHeader);
-		}
-
-	// Check to see if the authentication is valid for use. Anything could have gone wrong
-	// from bad credentials to wrong type of authentication etc.
-	if (!context->authentication || !CFHTTPAuthenticationIsValid(context->authentication, &err))
-		{
-		LogMsg("RetryWithHTTPAuth: ERROR!! Authentication failed");
-		if (context->authentication)
-			{
-			// Check for bad credentials and treat these separately
-			if (err.domain == kCFStreamErrorDomainHTTP && (err.error == kCFStreamErrorHTTPAuthenticationBadUserName ||
-				err.error == kCFStreamErrorHTTPAuthenticationBadPassword))
-				{
-				LogMsg("RetryWithHTTPAuth: ERROR!! Bad credentials %d", err.error); 
-				}
-			}
-		CancelHTTPDataStream(stream, context);
-		return;
-    	}
-
-	// Do we need username & password?  Not all authentication types require them.
-	if (CFHTTPAuthenticationRequiresUserNameAndPassword(context->authentication))
-		{
-		char username[MAX_DOMAIN_LABEL + 1];
-
-
-		// Use the first BTMM username and password
-		for (FoundInList = (&mDNSStorage)->AuthInfoList; FoundInList; FoundInList = FoundInList->next)
-			if (!FoundInList->deltime && FoundInList->AutoTunnel) break;
-
-		if (!FoundInList)
-			{
-			LogInfo("RetryHTTPWithAuth:  No BTMM credentials");
-			CancelHTTPDataStream(stream, context);
-			return;
-			}
-
-		ConvertDomainLabelToCString_unescaped((domainlabel *)FoundInList->domain.c, username);
-		CFStringRef user = CFStringCreateWithBytes(NULL, (const mDNSu8 *)username, strlen(username), kCFStringEncodingASCII, false);
-		if (!user)
-			{
-			LogMsg("RetryHTTPWithAuth: ERROR!! CFStringCreateWithBytes error");
-			CancelHTTPDataStream(stream, context);
-			return;
-			}
-		CFStringRef pass = CFStringCreateWithBytes(NULL, (const mDNSu8 *)FoundInList->b64keydata, strlen(FoundInList->b64keydata),
-			kCFStringEncodingASCII, false);
-		if (!pass)
-			{
-			LogMsg("RetryHTTPWithAuth: ERROR!! CFStringCreateWithBytes error");
-			CFRelease(user);
-			CancelHTTPDataStream(stream, context);
-			return;
-			}
-		// Build the credentials dictionary
-		credentials = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-		if (!credentials)
-			{
-			LogMsg("RetryHTTPWithAuth: ERROR!! cannot allocate credentials");
-			CFRelease(user);
-			CFRelease(pass);
-			CancelHTTPDataStream(stream, context);
-			return;
-			}
-		CFDictionarySetValue(credentials, kCFHTTPAuthenticationUsername, user);
-		CFDictionarySetValue(credentials, kCFHTTPAuthenticationPassword, pass);
-		CFRelease(user);
-		CFRelease(pass);
-        }
-	else
-		{
-		LogMsg("RetryHTTPWithAuth: ERROR!! Unknown authentication method");
-		CancelHTTPDataStream(stream, context);
-		return;
-		}
-
-	HTTPDataStream(context->url, context->op, context->bodyData, context->headerFieldName, context->headerFieldValue,
-		context->authentication, credentials, context->callback, &context->cbcontext);
-
-	if (credentials) CFRelease(credentials);
-
-	// Cancel the old one
-	CancelHTTPDataStream(stream, context);
-	}
-
-mDNSlocal void HTTPDataStreamCallback(CFReadStreamRef stream, CFStreamEventType type, void *info)
-	{
-	HTTPDataStreamContext *context = (HTTPDataStreamContext *)info;
-	CFIndex status;
-
-	status = HTTPResponseCode(stream);
-
-	// if we are forbidden to access, we need to refetch the configuration file.
-	// For keeping it simple, we don't retry immediately. When the next message
-	// is logged, we will try getting the config file. If we want to modify this
-	// in the future to retry now, then we need to know to stop retrying after a
-	// few times.
-	if ((status == kHTTPResponseCodeNotFound) || (status == kHTTPResponseCodeForbidden))
-		{
-		if (status == kHTTPResponseCodeNotFound)
-			LogMsg("HTTPDataStreamCallback: ERROR!! Config plist cannot be found");
-		else if (status == kHTTPResponseCodeForbidden)
-			LogInfo("HTTPDataStreamCallback: Config plist Forbidden by server");
-		if (context->callback) context->callback(context->responseData, &context->cbcontext);
-		CancelHTTPDataStream(stream, context);
-		return;
-		}
-
-	switch (type)
-		{
-		case kCFStreamEventHasBytesAvailable:
-			{
-			mDNSu8 buffer[kReadStreamBufferSize];
-			CFIndex bytesRead;
-				
-			if (!context->authChecked)
-				{
-				context->authChecked = mDNStrue;
-				if (status == kHTTPResponseCodeAuthFailure)
-					{
-					RetryWithHTTPAuth(context, stream);
-					return;
-					}
-				}
-				
-			bytesRead = CFReadStreamRead(stream, buffer, sizeof(buffer));
-			if (bytesRead > 0)
-				{
-				CFDataAppendBytes(context->responseData, buffer, bytesRead);
-				if (CFDataGetLength(context->responseData) > kMaximumResponseSize)
-					{
-					LogMsg("HTTPDataStreamCallback: ERROR!! Appended max data %d", kMaximumResponseSize);
-					}
-				else { LogInfo("HTTPDataStreamCallback: successfully appended data of size %ld", bytesRead); return; }
-				}
-			else if (bytesRead < 0)
-				{
-				LogMsg("HTTPDataStreamCallback: ERROR!! CFReadStreamRead returned %ld", bytesRead);
-				}
-			}
-			break;
-		case kCFStreamEventEndEncountered:
-			{
-			if (!context->authChecked)
-				{
-				context->authChecked = mDNStrue;
-				if (status == kHTTPResponseCodeAuthFailure)
-					{
-					RetryWithHTTPAuth(context, stream);
-					return;
-					}
-				}
-			if (status != kHTTPResponseCodeOK)
-				LogMsg("HTTPDataStreamCallback: ERROR!! EndEncountered, statusCode %d, Operation %d", status, context->op);
-			else
-				LogInfo("HTTPDataStreamCallback: HTTP Ok for Operation %d", context->op);
-			if (context->callback) context->callback(context->responseData, &context->cbcontext);
-			}
-			break;
-		case kCFStreamEventErrorOccurred:
-			LogInfo("HTTPDataStreamCallback: ERROR!! kCFStreamEventErrorOccurred for Operation %d", context->op);
-			if (context->callback) context->callback(context->responseData, &context->cbcontext);
-			break;
-		default:
-			LogMsg("HTTPDataStreamCallback: ERROR!! default case");
-			if (context->callback) context->callback(context->responseData, &context->cbcontext);
-			break;
-		}
-	CancelHTTPDataStream(stream, context);
-}
-
-// Everything needs to be copied or retained locally if need to be accessed beyond function scope
-mDNSlocal void HTTPDataStream(CFStringRef url, HTTPOperation op, CFDataRef bodyData, CFStringRef headerFieldName,
-	CFStringRef headerFieldValue, CFHTTPAuthenticationRef authentication, CFMutableDictionaryRef credentials,
-	HTTPClientCallback callback, ELogContext *cbcontext)
-	{
-	CFURLRef myURL = NULL;
-	CFHTTPMessageRef myRequest = NULL;
-	CFReadStreamRef readStream = NULL;
-	HTTPDataStreamContext *contextInfo = NULL;
-	CFDictionaryRef proxyDict = NULL;
-
-	contextInfo = mallocL("HTTPDataStreamContext", sizeof(HTTPDataStreamContext));
-	if (!contextInfo) { LogMsg("HTTPDataStream: mallocL failure"); return; }
-
-	mDNSPlatformMemZero(contextInfo, sizeof(*contextInfo));
-	// Need to remember the state, so that if we need to retry with authentication, we can
-	// reissue the request
-	contextInfo->url = CFRetain(url);
-	contextInfo->callback = callback;
-	if(cbcontext) memcpy(&contextInfo->cbcontext, cbcontext, sizeof(ELogContext));
-	contextInfo->authChecked = mDNSfalse;
-	contextInfo->op = op;
-	if (authentication) contextInfo->authentication = (CFHTTPAuthenticationRef) CFRetain(authentication);
-	if (headerFieldName) contextInfo->headerFieldName = CFRetain(headerFieldName);
-	if (headerFieldValue) contextInfo->headerFieldValue = CFRetain(headerFieldValue);
-	if (bodyData) contextInfo->bodyData = CFRetain(bodyData);
-
-	myURL = CFURLCreateWithString(kCFAllocatorDefault, url, NULL);
-	if (!myURL) { LogMsg("HTTPDataStream: CFURLCreateWithString error"); goto cleanup; }
-
-	CFStringRef requestMethod = op == HTTPGet ? CFSTR("GET") : CFSTR("POST");
-	myRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, myURL, kCFHTTPVersion1_1);
-	if (!myRequest) { LogMsg("HTTPDataStream: CFHTTPMessageCreateRequest error"); goto cleanup; }
-
-	if (bodyData) CFHTTPMessageSetBody(myRequest, bodyData);
-	if (headerFieldName) CFHTTPMessageSetHeaderFieldValue(myRequest, headerFieldName, headerFieldValue);
-
-	if (credentials)
-		{
-		if (!CFHTTPMessageApplyCredentialDictionary(myRequest, contextInfo->authentication, credentials, NULL))
-			{
-			LogMsg("HTTPDataStream: ERROR!! CFHTTPMessageApplyCredentialDictionary error");
-			goto cleanup;
-			}
-		}
-
-	readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest);
-	if (!readStream) { LogMsg("HTTPDataStream: CFStringCreateWithBytes error"); goto cleanup; }
-
-	proxyDict = SCDynamicStoreCopyProxies(NULL);
-	if (proxyDict)
-		{
-		mDNSBool ret = CFReadStreamSetProperty(readStream, kCFStreamPropertyHTTPProxy, proxyDict);
-		CFRelease(proxyDict);
-		if (!ret)
-			{
-			LogMsg("HTTPDataStream: CFReadStreamSetProperty HTTP proxy failed");
-			goto cleanup;
-			}
-		}
-
-	CFOptionFlags events = kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered;
-
-	CFStreamClientContext readContext = {0, contextInfo, NULL, NULL, NULL};
-	CFReadStreamSetClient(readStream, events, HTTPDataStreamCallback, &readContext);
-	CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetMain(), kCFRunLoopCommonModes);
-	if (CFReadStreamOpen(readStream))
-		{
-		contextInfo->responseData = CFDataCreateMutable(NULL, 0);
-		if (contextInfo->responseData)
-			{
-			// Release the things that we don't need
-			CFRelease(myURL);
-			CFRelease(myRequest);
-			return;
-			}
-		LogMsg("HTTPDataStream: ERROR!! responseData allocation failed");
-		}
-	else LogMsg("HTTPDataStream: ERROR!! CFReadStreamOpen failed");
-cleanup:
-	if (readStream) CancelReadStream(readStream);
-	if (myRequest) CFRelease(myRequest);
-	if (myURL) CFRelease(myURL);
-	if (contextInfo)
-		{
-		if (contextInfo->authentication) CFRelease(contextInfo->authentication);
-		if (contextInfo->headerFieldName) CFRelease(contextInfo->headerFieldName);
-		if (contextInfo->headerFieldValue) CFRelease(contextInfo->headerFieldValue);
-		if (contextInfo->bodyData) CFRelease(contextInfo->bodyData);
-		if (contextInfo->url) CFRelease(contextInfo->url);
-		freeL("HTTPDataStreamContext", contextInfo);
-		}
-	}
-
-mDNSlocal CFStringRef eReporterGetValueForKey(CFDictionaryRef dict, char *keyCString)
-	{
-	CFStringRef value;
-	CFStringRef key;
-
-	key = CFStringCreateWithCString(NULL, keyCString, kCFStringEncodingUTF8);
-	if (!CFDictionaryContainsKey(dict, key))
-		{
-		LogMsg("eReporterGetValueForKey: ERROR!! key %s not found", keyCString);
-		return NULL;
-		}
-	value = (CFStringRef)CFDictionaryGetValue(dict, key);
-	CFRelease(key);
-	if (!value)
-		{
-		LogMsg("eReporterGetValueForKey: ERROR!! value not found for %s", keyCString);
-		return NULL;
-		}
-	return value;
-	}
-	
-mDNSlocal void eReporterConfigCallback(CFMutableDataRef responseData, ELogContext *context)
-	{
-	CFDictionaryRef dict = NULL;
-	char *plistKeys[] = {"URL", "Publish", "LoadText", "URI", NULL};
-	int i;
-	CFErrorRef error;
-
-	if (!CFDataGetLength(responseData))
-		{
-		LogInfo("eReporterConfigCallback: Zero length data");
-		eReporterConfig.eRState = ConfigInvalid;
-		return;
-		}
-	CFPropertyListFormat format = kCFPropertyListXMLFormat_v1_0;
-	dict = CFPropertyListCreateWithData(0, responseData, kCFPropertyListImmutable, &format, &error);
-	if ( dict == NULL )
-		{
-		LogMsg("eReporterConfigCallback: Parsing property list failed");
-		eReporterConfig.eRState = ConfigInvalid;
-		CFRelease(error);
-		return;
-		}
-	i = 0;
-	while (plistKeys[i] != NULL)
-		{
-		if (eReporterGetValueForKey(dict, plistKeys[i]) == NULL)
-			{
-			LogMsg("eReporterConfigCallback: ERROR!! problem accessing key %s", plistKeys[i]);
-			CFRelease(dict);
-			eReporterConfig.eRState = ConfigInvalid;
-			return;
-			}
-		i++;
-		}
-	if (eReporterConfig.eRDict) CFRelease(eReporterConfig.eRDict);
-	eReporterConfig.eRDict = dict;
-	eReporterConfig.eRState = ConfigValid;
-	mDNSReporterLogValidConfig(context);
-	}
-
-mDNSlocal mDNSBool FetchEReporterConfiguration(ELogContext *context)
-	{
-	const char *urlString = "https://configuration.apple.com./configurations/internetservices/e3/mDNSResponder/Configurations1.0.plist";
-	//const char *urlString = "http://isdev02:9702/configuration/configurations/internetservices/e3/btmm/Configurations1.0.plist"; //dev server
-
-	CFStringRef url = CFStringCreateWithBytes(NULL, (const mDNSu8 *)urlString, strlen(urlString), kCFStringEncodingASCII, false);
-	if (!url) { LogMsg("FetchEReporterConfiguration: CFStringCreateWithBytes error"); return mDNSfalse; }
-
-	if (eReporterConfig.eRState == ConfigValid || eReporterConfig.eRState == ConfigFetching)
-		{
-		CFRelease(url);
-		return mDNSfalse;
-		}
-
-	eReporterConfig.eRState = ConfigFetching;
-	HTTPDataStream(url, HTTPGet, NULL, NULL, NULL, NULL, NULL, eReporterConfigCallback, context);
-	CFRelease(url);
-	return mDNStrue;
-	}
-
-// Builds an element of type : <key name="nameAttr"> value </key> and attaches it to
-// xmlTree
-mDNSlocal mDNSBool AddElementToTree(CFXMLTreeRef xmlTree, char *nameAttr, char *value)
-	{
-	/* <key name="BTMM domain"> domain </key> */
-
-	CFStringRef textval = CFStringCreateWithCString(NULL, value, kCFStringEncodingUTF8);
-	if (!textval) { LogMsg("AddElementToTree: cannot create CString for value %s", value); return mDNSfalse; }
-
-	CFStringRef keys[1] = { CFSTR("name") };
-	CFStringRef values[1] = { CFStringCreateWithCString(NULL, nameAttr, kCFStringEncodingUTF8) };
-
-	CFDictionaryRef dict = CFDictionaryCreate(NULL, (void*)keys, (void*)values, 1, &kCFTypeDictionaryKeyCallBacks,
-		&kCFTypeDictionaryValueCallBacks);
-	if (!dict)
-		{
-		LogMsg("AddElementToTree: ERROR!! CFDictionaryCreate failed for %s", nameAttr);
-		CFRelease(textval);
-		CFRelease(values[0]);
-		return mDNSfalse;
-		}
-
-	CFMutableArrayRef attr = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-	if (!attr)
-		{
-		LogMsg("AddElementToTree: ERROR!! CFArrayCreateMutable failed for %s", nameAttr);
-		CFRelease(textval);
-		CFRelease(dict);
-		CFRelease(values[0]);
-		return mDNSfalse;
-		}
-
-	CFArrayAppendValue(attr, keys[0]);
-
-	/* Build <key name="nameAttr"> */
-
-	CFXMLElementInfo nameInfo;
-	nameInfo.attributes = (CFDictionaryRef)dict;
-	nameInfo.attributeOrder = (CFArrayRef) attr;
-	nameInfo.isEmpty = mDNSfalse;	
-	CFXMLNodeRef nameNode = CFXMLNodeCreate(kCFAllocatorDefault, kCFXMLNodeTypeElement, CFSTR("key"), &nameInfo,
-		kCFXMLNodeCurrentVersion);	
-	CFXMLTreeRef nameTree = CFXMLTreeCreateWithNode(kCFAllocatorDefault, nameNode);
-	CFTreeAppendChild(xmlTree, nameTree);
-	CFRelease(nameNode);
-	CFRelease(attr);
-	CFRelease(dict);
-	CFRelease(values[0]);
-
-	/* Build the rest: value </key> */
-
-	CFXMLNodeRef nameTextNode = CFXMLNodeCreate(kCFAllocatorDefault, kCFXMLNodeTypeText, textval, NULL,
-	   kCFXMLNodeCurrentVersion);	
-	CFXMLTreeRef nameTextTree = CFXMLTreeCreateWithNode(kCFAllocatorDefault, nameTextNode);
-	CFTreeAppendChild(nameTree, nameTextTree);
-	CFRelease(nameTextTree);
-	CFRelease(nameTextNode);
-	CFRelease(textval);
-
-	// Now that we are done with nameTree, we can release it
-	CFRelease(nameTree);
-
-	return mDNStrue;
-	}
-
-mDNSlocal void LogPOSTArgs(CFStringRef finalURL, CFStringRef LoadTextName, CFStringRef LoadTextValue, CFDataRef bodyData)
-	{
-	char buf1[128], buf2[64], buf3[64], buf4[1024];
-
-	if (!CFStringGetCString(finalURL, buf1, sizeof(buf1), kCFStringEncodingUTF8) ||
-		!CFStringGetCString(LoadTextName, buf2, sizeof(buf2), kCFStringEncodingUTF8) ||
-		!CFStringGetCString(LoadTextValue, buf3, sizeof(buf3), kCFStringEncodingUTF8))
-		{
-		LogMsg("mDNSEReportPOSTArgs: Error in parsing arguments");
-		return;	
-		}
-	CFStringRef bstr = CFStringCreateFromExternalRepresentation(NULL, bodyData, kCFStringEncodingUTF8);
-	buf4[0] = 0;
-	if (!CFStringGetCString(bstr, buf4, sizeof(buf4), kCFStringEncodingUTF8))
-		{
-		LogMsg("mDNSEReportPOSTArgs: buf4 cstring conversion problem");
-		}
-	if (bstr) CFRelease(bstr);
-	LogInfo("LogPOSTArgs: URL : %s, LoadTextName: %s, LoadTextValue: %s, bodyData %s", buf1, buf2, buf3, buf4);
-	}
-
-// This function is called when there is a valid configuration for eReporter service
-// We add the following:
-//
-// <key name="uuid"> uuid </key>
-// <key name="Subdomain"> subdomain </key>
-// <key name="Message"> message </key>
-// <key name="Time"> YYYY-MM-DD HH24:MI:SS </key>
-// <key name="SPS"> True/False </key>
-// <key name="Result"> Success/Fail </key>
-//
-// if result is -1, result won't be added. 1 means "Failed" and 0 means "Success"
-//
-mDNSlocal void mDNSReporterLogValidConfig(ELogContext *elog)
-	{
-	CFMutableStringRef finalURL = NULL;
-	CFStringRef LoadTextName = NULL;
-	CFDataRef bodyData = NULL;
-	CFBooleanRef pub;
-	CFXMLTreeRef appTree = NULL;
-
-	pub = (CFBooleanRef)eReporterGetValueForKey(eReporterConfig.eRDict, "Publish");
-	if (pub == NULL)
-		{
-		LogMsg("mDNSReporterLogValidConfig: Publish key does not exist");
-		return;
-		}
-
-	Boolean pubVal = CFBooleanGetValue(pub);
-	if (!pubVal)
-		{
-		// Set the config state to invalid so that we will refetch the configuration next time
-		// in case Publish value changes between now and then
-		eReporterConfig.eRState = ConfigInvalid;
-		LogInfo("mDNSReporterLogValidConfig: Value for Publish is %d", pubVal);
-		return;
-		}
-
-	CFXMLDocumentInfo documentInfo;
-	documentInfo.sourceURL = NULL;
-	documentInfo.encoding = kCFStringEncodingUTF8;
-	CFXMLNodeRef docNode = CFXMLNodeCreate( kCFAllocatorDefault, kCFXMLNodeTypeDocument, CFSTR(""), &documentInfo,
-		kCFXMLNodeCurrentVersion);
-	CFXMLTreeRef xmlDocument = CFXMLTreeCreateWithNode(kCFAllocatorDefault, docNode);
-	CFRelease(docNode);
-
-	/* <?xml version="1.0" encoding="utf-8"?> */
-	CFXMLProcessingInstructionInfo instructionInfo;
-	instructionInfo.dataString = CFSTR("version=\"1.0\" encoding=\"utf-8\"");
-	CFXMLNodeRef instructionNode = CFXMLNodeCreate(NULL, kCFXMLNodeTypeProcessingInstruction, CFSTR("xml"),
-		&instructionInfo, kCFXMLNodeCurrentVersion);
-	CFXMLTreeRef instructionTree = CFXMLTreeCreateWithNode(kCFAllocatorDefault, instructionNode);
-	CFTreeAppendChild(xmlDocument, instructionTree);
-	CFRelease(instructionTree);
-	CFRelease(instructionNode);
-
-	/* Root Element: <app name="mDNSResponder" version="XXX"> */
-
-	CFStringRef appKeys[2] = { CFSTR("name"), CFSTR("version") };
-	CFStringRef appValues[2] = { CFStringCreateWithCString(NULL, "mDNSResponder", kCFStringEncodingUTF8),
-								 CFStringCreateWithCString(NULL, STRINGIFY(mDNSResponderVersion), kCFStringEncodingUTF8) };
-
-	CFDictionaryRef appDict = CFDictionaryCreate(NULL, (void*)appKeys, (void*)appValues, 2, &kCFTypeDictionaryKeyCallBacks,
-		&kCFTypeDictionaryValueCallBacks);
-	if (!appDict) { LogMsg("mDNSEReporterLogValidConfig: CFDictionaryCreate App failed"); goto cleanup; }
-
-	CFMutableArrayRef appAttr = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-	if (!appAttr) { LogMsg("mDNSEReporterLogValidConfig: CFArrayCreateMutable App failed"); goto cleanup; }
-
-	CFArrayAppendValue(appAttr, appKeys[0]);
-	CFArrayAppendValue(appAttr, appKeys[1]);
-
-	CFXMLElementInfo appInfo;
-	appInfo.attributes = (CFDictionaryRef) appDict;
-	appInfo.attributeOrder = (CFArrayRef) appAttr;
-	appInfo.isEmpty = mDNSfalse;
-	CFXMLNodeRef appNode = CFXMLNodeCreate ( kCFAllocatorDefault, kCFXMLNodeTypeElement, CFSTR("app"), &appInfo,
-		kCFXMLNodeCurrentVersion);	
-	appTree = CFXMLTreeCreateWithNode(kCFAllocatorDefault, appNode);
-	CFTreeAppendChild(xmlDocument, appTree);
-	CFRelease(appNode);
-	CFRelease(appAttr);
-	CFRelease(appDict);
-	CFRelease(appValues[0]);
-	CFRelease(appValues[1]);
-	// appTree will be released at the end as we will be appeneding other nodes to appTree below
-
-	char		uuidStr[37];
-	uuid_unparse(elog->uuid, uuidStr);
-	AddElementToTree(appTree, "UUID", uuidStr);
-
-	AddElementToTree(appTree, "Subdomain", elog->subdomain);
-	AddElementToTree(appTree, "Message", elog->message);
-
-	char tm_buffer[128];
-	time_t t = time(NULL);
-	struct tm *tm_t = gmtime(&t);
-	mDNS_snprintf(tm_buffer, sizeof(tm_buffer), "%4d-%02d-%02d %02d:%02d:%02d", tm_t->tm_year + 1900, tm_t->tm_mon + 1,
-		tm_t->tm_mday, tm_t->tm_hour, tm_t->tm_min, tm_t->tm_sec);
-	AddElementToTree(appTree, "Time", tm_buffer);
-
-	const CacheRecord *sps[3] = { mDNSNULL };
-	NetworkInterfaceInfo *intf;
-	mDNSBool SleepProxy = mDNSfalse;
-	for (intf = GetFirstActiveInterface(mDNSStorage.HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
-		{
-		if (intf->NetWake)
-			{
-			FindSPSInCache(&mDNSStorage, &intf->NetWakeBrowse, sps);
-			if (sps[0])
-				{
-				SleepProxy = mDNStrue;
-				break;
-				}
-			}
-		else { LogInfo("mDNSEReporterValidConfig: NetWake is not set %p", intf->InterfaceID); }
-		}
-	AddElementToTree(appTree, "SPS", (SleepProxy ? "True" : "False"));
-
-	if (elog->result != -1)
-		AddElementToTree(appTree, "Result", elog->result ? "fail" : "success");
-
-	bodyData = CFXMLTreeCreateXMLData(NULL, xmlDocument);
-	if (!bodyData) { LogMsg("mDNSEReporterLogValidConfig: CFXMLTreeCreateData failed for bodyData"); goto cleanup; }
-
-	CFStringRef url = eReporterGetValueForKey(eReporterConfig.eRDict, "URL");
-	if (!url) { LogMsg("mDNSEReporterLogValidConfig: eReporterGetValueForKey failed for URL"); goto cleanup; }
-
-	CFStringRef uri = eReporterGetValueForKey(eReporterConfig.eRDict, "URI");
-	if (!uri) { LogMsg("mDNSEReporterLogValidConfig: eReporterGetValueForKey failed for URI"); goto cleanup; }
-
-	finalURL = CFStringCreateMutable(NULL, 0);
-	if (!finalURL) { LogMsg("mDNSEReporterLogValidConfig: CFStringCreateMutable failed for finalURL"); goto cleanup; }
-
-	CFStringAppend(finalURL, url);
-	CFStringAppend(finalURL, uri);
-
-	LoadTextName = CFStringCreateWithCString(NULL, "x-LoadText", kCFStringEncodingUTF8);
-	if (!LoadTextName) { LogMsg("mDNSEReporterLogValidConfig: CFStringCreateWithCString failed for LoadText"); goto cleanup; }
-
-	CFStringRef LoadTextValue = eReporterGetValueForKey(eReporterConfig.eRDict, "LoadText");	
-	if (!LoadTextValue) { LogMsg("mDNSEReporterLogValidConfig: eReporterGetValueForKey failed for LoadTextValue"); goto cleanup; }
-
-	LogPOSTArgs(finalURL, LoadTextName, LoadTextValue, bodyData);
-
-	// we don't have a callback for the POST. If there is an error in POST, it will be logged
-	// by the callback of HTTPDataStream
-	HTTPDataStream(finalURL, HTTPPost, bodyData, LoadTextName, LoadTextValue, NULL, NULL, NULL, NULL);
-
-cleanup:
-	// Free whatever was allocated in this function
-	if (bodyData) CFRelease(bodyData);
-	if (finalURL) CFRelease(finalURL);
-	if (LoadTextName) CFRelease(LoadTextName);
-	if (appTree) CFRelease(appTree);
-	CFRelease(xmlDocument);
-	}
-
-mDNSlocal void mDNSEReporterLog(uuid_t *uuid, const char *subdomain, int result, char *message)
-	{
-	// We allocate ELogContext and free it at the end of the function. It is the
-	// responsibility of the called function to copy it if it needs to hold
-	// on to it
-	ELogContext *info = mallocL("ELogContext", sizeof (ELogContext));
-	if (!info) { LogMsg("mDNSEReporterLog: malloc failed"); return; }
-
-	// Take a local copy of all the log information
-	strlcpy(info->subdomain, subdomain, sizeof(info->subdomain));
-	strlcpy(info->message, message, sizeof(info->message));
-	info->result = result;
-	uuid_copy(info->uuid, *uuid);
-	if (eReporterConfig.eRState != ConfigValid)
-		{
-		// Currently we can't have two outstanding configuration fetches. If we have two quick
-		// back to back logs while the configuration is being fetched, we log only the first
-		// message to EReporter. If the configuration is valid (common case), then we don't
-		// drop any messages
-		if (!FetchEReporterConfiguration(info))
-			{
-			LogInfo("mDNSEReporterLog: Configuration being fetched.., Not logging");
-			}
-		freeL("ELogContext", info);
-		return;
-		}
-	mDNSReporterLogValidConfig(info);
-	freeL("ELogContext", info);
-	}
-
 #ifndef NO_SECURITYFRAMEWORK
 
 static CFMutableDictionaryRef domainStatusDict = NULL;
@@ -3983,10 +3263,10 @@
 			}
 		}
 	
-	// If we have a relay address, check the LLQ status as they don't go over the relay connection.
-	// If LLQs fail, then report failure. In future, when LLQs go over the relay connection, we don't
-	// need this logic
-	if (!mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddr))
+	// If we have a relay address which lets other hosts to reach us through the relay, then we should
+	// report success except for the LLQs they don't go over the relay connection. If LLQs fail, then
+	// report failure. In future, when LLQs go over the relay connection, we don't need this logic
+	if (!mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddrIn))
 		{
 		// If we have a bad signature error updating RR, it overrides any error as
 		// the user needs to be notified immediately 
@@ -4079,7 +3359,6 @@
 			static char statusBuf[16];
 			mDNS_snprintf(statusBuf, sizeof(statusBuf), "%d", (int)status);
 			mDNSASLLog((uuid_t *)&m->asl_uuid, "autotunnel.domainstatus", status ? "failure" : "success", statusBuf, "");
-			mDNSEReporterLog((uuid_t *)&m->asl_uuid, "autotunnel.domainstatus", status, statusBuf);
 			mDNSDynamicStoreSetConfig(kmDNSBackToMyMacConfig, mDNSNULL, domainStatusDict);
 			}
 		}
@@ -4087,7 +3366,6 @@
 	CFRelease(domain);
 	CFRelease(dict);
 
-
 	debugf("UpdateAutoTunnelDomainStatus: %s", buffer);
 #endif // def NO_SECURITYFRAMEWORK
 	}
@@ -4135,7 +3413,7 @@
 	DomainAuthInfo *info;
 	
 	for (info = m->AuthInfoList; info; info = info->next)
-		if (info->AutoTunnel && !info->deltime && (!mDNSIPPortIsZero(info->AutoTunnelNAT.ExternalPort) || !mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddr)))
+		if (info->AutoTunnel && !info->deltime && (!mDNSIPPortIsZero(info->AutoTunnelNAT.ExternalPort) || !mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddrIn)))
 			break;
 	
 	if (info != AnonymousRacoonConfig)
@@ -4167,7 +3445,7 @@
 
 	NATProblem = mDNSIPPortIsZero(info->AutoTunnelNAT.ExternalPort) || info->AutoTunnelNAT.Result;
 
-	if (mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddr))
+	if (mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddrIn))
 		{
 		// If we don't have a relay address, check to see if we are behind a Double NAT or NAT with no NAT-PMP
 		// support.  
@@ -4420,16 +3698,16 @@
 	// change, so check to see if the value has changed. This can also be zero when we are deregistering and
 	// getting called from the AutoTunnelRecordCallback
 
-	if (mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddr))
+	if (mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddrIn))
 		{
 		LogInfo("RegisterAutoTunnel6Record: Relay address is zero, not registering");
 		return;
 		}
 
 	if ((info->AutoTunnel6Record.resrec.RecordType > kDNSRecordTypeDeregistering) &&
-		(mDNSSameIPv6Address(info->AutoTunnel6Record.resrec.rdata->u.ipv6, m->AutoTunnelRelayAddr)))
+		(mDNSSameIPv6Address(info->AutoTunnel6Record.resrec.rdata->u.ipv6, m->AutoTunnelRelayAddrIn)))
 		{
-		LogInfo("RegisterAutoTunnel6Record: Relay address %.16a same, not registering", &m->AutoTunnelRelayAddr);
+		LogInfo("RegisterAutoTunnel6Record: Relay address %.16a same, not registering", &m->AutoTunnelRelayAddrIn);
 		return;
 		}
 
@@ -4451,7 +3729,7 @@
 		AssignDomainName (&info->AutoTunnel6Record.namestorage, (const domainname*) "\x0C" "_autotunnel6");
 		AppendDomainLabel(&info->AutoTunnel6Record.namestorage, &m->hostlabel);
 		AppendDomainName (&info->AutoTunnel6Record.namestorage, &info->domain);
-		info->AutoTunnel6Record.resrec.rdata->u.ipv6 = m->AutoTunnelRelayAddr;
+		info->AutoTunnel6Record.resrec.rdata->u.ipv6 = m->AutoTunnelRelayAddrIn;
 		info->AutoTunnel6Record.resrec.RecordType = kDNSRecordTypeKnownUnique;
 
 		err = mDNS_Register_internal(m, &info->AutoTunnel6Record);
@@ -4459,10 +3737,10 @@
 		else LogInfo("RegisterAutoTunnel6Record registering AutoTunnel6 Record %##s", info->AutoTunnel6Record.namestorage.c);
 
 		LogInfo("AutoTunnel6 server listening for connections on %##s[%.16a] :%##s[%.16a]",
-			info->AutoTunnel6Record.namestorage.c,     &m->AutoTunnelRelayAddr,
+			info->AutoTunnel6Record.namestorage.c,     &m->AutoTunnelRelayAddrIn,
 			info->AutoTunnelHostRecord.namestorage.c, &m->AutoTunnelHostAddr);
 
-		} else {LogInfo("RegisterAutoTunnel6Record: client context %p, RequestedPort %d, Address %.16a, record type %d", info->AutoTunnelNAT.clientContext, info->AutoTunnelNAT.RequestedPort, &m->AutoTunnelRelayAddr, info->AutoTunnel6Record.resrec.RecordType);}
+		} else {LogInfo("RegisterAutoTunnel6Record: client context %p, RequestedPort %d, Address %.16a, record type %d", info->AutoTunnelNAT.clientContext, info->AutoTunnelNAT.RequestedPort, &m->AutoTunnelRelayAddrIn, info->AutoTunnel6Record.resrec.RecordType);}
 
 	RegisterAutoTunnelHostRecord(m, info);
 	// When the AutoTunnel6 record comes up, we need to kick racoon and update the status.
@@ -4914,7 +4192,7 @@
 		{
 		LogInfo("TunnelClientFinish: Relay address %.16a", &answer->rdata->u.ipv6);
 		tun->rmt_outer6 = answer->rdata->u.ipv6;
-		tun->loc_outer6 = m->AutoTunnelRelayAddr;
+		tun->loc_outer6 = m->AutoTunnelRelayAddrOut;
 		}
 	else
 		{
@@ -4945,9 +4223,8 @@
 
 	mStatus result = needSetKeys ? AutoTunnelSetKeys(tun, mDNStrue) : mStatus_NoError;
 	static char msgbuf[32];
-	mDNS_snprintf(msgbuf, sizeof(msgbuf), "Client AutoTunnel setup - %d", result);
+	mDNS_snprintf(msgbuf, sizeof(msgbuf), "Tunnel setup - %d", result);
 	mDNSASLLog((uuid_t *)&m->asl_uuid, "autotunnel.config", result ? "failure" : "success", msgbuf, "");
-	mDNSEReporterLog((uuid_t *)&m->asl_uuid, "autotunnel.config", result, msgbuf);
 	// Kick off any questions that were held pending this tunnel setup
 	ReissueBlockedQuestions(m, &tun->dstname, (result == mStatus_NoError) ? mDNStrue : mDNSfalse);
 	}
@@ -4969,7 +4246,6 @@
 		static char msgbuf[16];
 		mDNS_snprintf(msgbuf, sizeof(msgbuf), "%s lookup", DNSTypeName(question->qtype));
 		mDNSASLLog((uuid_t *)&m->asl_uuid, "autotunnel.config", "failure", msgbuf, "");
-		mDNSEReporterLog((uuid_t *)&m->asl_uuid, "autotunnel.config", 1, msgbuf);
 		UnlinkAndReissueBlockedQuestions(m, tun, mDNSfalse);
 		return;
 		}
@@ -4989,7 +4265,7 @@
 				}
 			tun->rmt_inner = answer->rdata->u.ipv6;
 			LogInfo("AutoTunnelCallback:TC_STATE_AAAA_PEER: dst host %.16a", &tun->rmt_inner);
-			if (!mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddr))
+			if (!mDNSIPv6AddressIsZero(m->AutoTunnelRelayAddrOut))
 				{
 				LogInfo("AutoTunnelCallback: Looking up _autotunnel6 AAAA");
 				tun->tc_state = TC_STATE_AAAA_PEER_RELAY;
@@ -7096,9 +6372,9 @@
 	// Set the address to zero before calling DeregisterAutoTunnel6Record. If we call
 	// Deregister too quickly before the previous Register completed (just scheduled
 	// to be sent out) and when DeregisterAutoTunnel6Record calls mDNS_Register_internal,
-	// it invokes the AutoTunnelRecordCallback immediately and AutoTunnelRelayAddr should
+	// it invokes the AutoTunnelRecordCallback immediately and AutoTunnelRelayAddrIn should
 	// be zero so that we don't register again.
-	m->AutoTunnelRelayAddr = zerov6Addr;
+	m->AutoTunnelRelayAddrIn = zerov6Addr;
 	if (!m->AuthInfoList) LogInfo("RemoveAutoTunnel6Record: No Domain AuthInfo");
 	for (info = m->AuthInfoList; info; info = info->next)
 		{
@@ -7172,7 +6448,19 @@
 		return;
 		}
 	
-	m->AutoTunnelRelayAddr = v6addr;
+	m->AutoTunnelRelayAddrOut = v6addr;
+
+	// if disabled administratively, don't bother to register. RegisterAutoTunnel6Record makes these same
+	// checks, but we do it here not just as an optimization but mainly to keep AutoTunnelRelayAddrIn zero
+	// as a non-zero AutoTunnelRelayAddrIn indicates that we have registered _autotunnel6 record and hence
+	// other hosts can connect to this host through the relay
+	if (!m->RegisterAutoTunnel6 || DisableInboundRelayConnection)
+		{
+		LogInfo("RegisterAutoTunnel6Record: registration Disabled RegisterAutoTunnel6 %d, DisableInbound %d",
+			m->RegisterAutoTunnel6, DisableInboundRelayConnection);
+		return;
+		}
+	m->AutoTunnelRelayAddrIn = v6addr;
 
 	if (!m->AuthInfoList) LogInfo("AddAutoTunnel6Record: No Domain AuthInfo");
 	for (info = m->AuthInfoList; info; info = info->next)
@@ -7204,6 +6492,9 @@
 		{
 		LogInfo("ParseBackToMyMac: CFDictionaryGetValue No value for BackToMyMac, Removing autotunnel6");
 		RemoveAutoTunnel6Record(m);
+		// Note: AutoTunnelRelayAddrIn is zeroed out in RemoveAutoTunnel6Record as it is called
+		// from other places.
+		m->AutoTunnelRelayAddrOut = zerov6Addr;
 		return;
 		}
 
@@ -7212,6 +6503,7 @@
 		{
 		LogInfo("ParseBackToMyMac: NULL value for Interface, Removing autotunnel6"); 
 		RemoveAutoTunnel6Record(m);
+		m->AutoTunnelRelayAddrOut = zerov6Addr;
 		// We don't have a utun interface, start the relay connection if possible
 		UpdateBTMMRelayConnection(m);
 		}
@@ -7293,11 +6585,11 @@
 				else
 					{
 					if (!mDNSSameIPv6Address(p->loc_inner, m->AutoTunnelHostAddr) ||
-						!mDNSSameIPv6Address(p->loc_outer6, m->AutoTunnelRelayAddr))
+						!mDNSSameIPv6Address(p->loc_outer6, m->AutoTunnelRelayAddrOut))
 						{
 						AutoTunnelSetKeys(p, mDNSfalse);
 						p->loc_inner = m->AutoTunnelHostAddr;
-						p->loc_outer6 = m->AutoTunnelRelayAddr;
+						p->loc_outer6 = m->AutoTunnelRelayAddrOut;
 						AutoTunnelSetKeys(p, mDNStrue);
 						}
 					}
@@ -7647,7 +6939,14 @@
 			msg.k.event_code == KEV_DL_LINK_ADDRESS_CHANGED ? "KEV_DL_LINK_ADDRESS_CHANGED" :
 			msg.k.event_code == KEV_DL_WAKEFLAGS_CHANGED    ? "KEV_DL_WAKEFLAGS_CHANGED"    : "?");
 
-		if (msg.k.event_code == KEV_DL_WAKEFLAGS_CHANGED) SetNetworkChanged(m, mDNSPlatformOneSecond * 2);
+		// We receive network change notifications both through configd and through SYSPROTO_EVENT socket.
+		// Configd may not generate network change events for manually configured interfaces (i.e., non-DHCP)
+		// always during sleep/wakeup due to some race conditions (See radar:8666757). At the same time, if
+		// "Wake on Network Access" is not turned on, the notification will not have KEV_DL_WAKEFLAGS_CHANGED.
+		// Hence, during wake up, if we see a KEV_DL_LINK_ON (i.e., link is UP), we trigger a network change.
+
+		if (msg.k.event_code == KEV_DL_WAKEFLAGS_CHANGED || msg.k.event_code == KEV_DL_LINK_ON)
+			SetNetworkChanged(m, mDNSPlatformOneSecond * 2);
 		}
 
 	mDNS_Unlock(m);
@@ -8039,7 +7338,8 @@
 #endif
 
 	m->AutoTunnelHostAddr.b[0] = 0;		// Zero out AutoTunnelHostAddr so UpdateInterfaceList() know it has to set it up
-	m->AutoTunnelRelayAddr = zerov6Addr;
+	m->AutoTunnelRelayAddrIn = zerov6Addr;
+	m->AutoTunnelRelayAddrOut = zerov6Addr;
 
 	NetworkChangedKey_IPv4         = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4);
 	NetworkChangedKey_IPv6         = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv6);
diff --git a/mDNSMacOSX/mDNSResponder.sb b/mDNSMacOSX/mDNSResponder.sb
index 547f383..323ba3d 100644
--- a/mDNSMacOSX/mDNSResponder.sb
+++ b/mDNSMacOSX/mDNSResponder.sb
@@ -113,6 +113,11 @@
 ; Allow access to System Keychain
 (allow file-read-data                 (regex #"^/System/Library/Security$"))
 (allow file-read-data                 (regex #"^/System/Library/Keychains/.*$"))
+; We just need access to System.keychain. But we don't want errors logged if other keychains are
+; accessed under /Library/Keychains. Other keychains may be accessed as part of setting up an SSL
+; connection. Instead of adding access to it here(to things which we don't need), we disable any
+; logging that might happen during the access
+(deny  file-read-data                 (regex #"^/Library/Keychains/") (with no-log))
 (allow file-read-data                 (regex #"^/Library/Keychains/System\.keychain$"))
 ; Our Module Directory Services cache
 (allow file-read-data                 (regex #"^/private/var/tmp/mds/"))
@@ -135,7 +140,6 @@
 (allow file-read-data (regex #"^/System/Library/PrivateFrameworks/DeviceToDeviceManager.framework(/|$)"))
 (allow file-read-data (regex #"^/System/Library/PrivateFrameworks/MobileBluetooth.framework(/|$)"))
 (allow file-read-data (regex #"^/System/Library/Frameworks/CoreFoundation.framework(/|$)"))
-(allow file-read-data (regex #"^/System/Library/Frameworks/CoreServices.framework(/|$)"))
 (allow file-read-data (regex #"^/System/Library/Frameworks/SystemConfiguration.framework(/|$)"))
 (allow file-read-data (regex #"^/System/Library/Frameworks/IOKit.framework(/|$)"))
 (allow file-read-data (regex #"^/System/Library/Frameworks/Security.framework(/|$)"))
diff --git a/mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj b/mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj
index 81d5baf..88c0d94 100644
--- a/mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj
+++ b/mDNSMacOSX/mDNSResponder.xcodeproj/project.pbxproj
@@ -66,8 +66,6 @@
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
-		21E53F0F1219D1B3003EEE05 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21E53F0E1219D1B3003EEE05 /* CoreServices.framework */; };
-		21E53F141219D1CA003EEE05 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21E53F0E1219D1B3003EEE05 /* CoreServices.framework */; };
 		2E0405F50C3195F700F13B59 /* helper.c in Sources */ = {isa = PBXBuildFile; fileRef = 2E0405F40C3195F700F13B59 /* helper.c */; };
 		2E0405F60C31961100F13B59 /* helpermsg.defs in Sources */ = {isa = PBXBuildFile; fileRef = 2E0405EB0C3190DC00F13B59 /* helpermsg.defs */; settings = {ATTRIBUTES = (Server, Client, ); COMPILER_FLAGS = "-Wno-error"; }; };
 		2E0406150C3197CB00F13B59 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E0406140C3197CB00F13B59 /* libbsm.dylib */; };
@@ -444,7 +442,6 @@
 		000753D303367C1C0CCA2C71 /* mDNSMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mDNSMacOSX.h; sourceTree = "<group>"; };
 		00CA213D02786FC30CCA2C71 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
 		09AB6884FE841BABC02AAC07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
-		21E53F0E1219D1B3003EEE05 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
 		21F432971134AA6800581B69 /* WebFilterDNS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebFilterDNS.framework; path = /System/Library/PrivateFrameworks/WebFilterDNS.framework; sourceTree = "<absolute>"; };
 		2E0405EB0C3190DC00F13B59 /* helpermsg.defs */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.mig; path = helpermsg.defs; sourceTree = "<group>"; };
 		2E0405F00C31955500F13B59 /* mDNSResponderHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = mDNSResponderHelper; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -577,7 +574,6 @@
 				D284BE660ADD80740027CCDF /* SystemConfiguration.framework in Frameworks */,
 				D284BE670ADD80740027CCDF /* IOKit.framework in Frameworks */,
 				D284BE680ADD80740027CCDF /* Security.framework in Frameworks */,
-				21E53F0F1219D1B3003EEE05 /* CoreServices.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -589,7 +585,6 @@
 				D284BE8E0ADD80800027CCDF /* SystemConfiguration.framework in Frameworks */,
 				D284BE8F0ADD80800027CCDF /* IOKit.framework in Frameworks */,
 				D284BE900ADD80800027CCDF /* Security.framework in Frameworks */,
-				21E53F141219D1CA003EEE05 /* CoreServices.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -685,7 +680,6 @@
 				FFFB0DA407B43BED00B88D48 /* PreferencePane */,
 				08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */,
 				19C28FBDFE9D53C911CA2CBB /* Products */,
-				21E53F0E1219D1B3003EEE05 /* CoreServices.framework */,
 			);
 			name = mDNSResponder;
 			sourceTree = "<group>";
diff --git a/mDNSShared/DebugServices.h b/mDNSShared/DebugServices.h
index 28cd2e7..d4e5c72 100644
--- a/mDNSShared/DebugServices.h
+++ b/mDNSShared/DebugServices.h
@@ -500,9 +500,7 @@
 	work with GCC due to GCC allow a zero-length array. Using a -1 condition turned out to be more portable.
 */
 
-#ifndef check_compile_time
 #define	check_compile_time( X )		extern int debug_compile_time_name[ ( X ) ? 1 : -1 ]
-#endif
 
 //---------------------------------------------------------------------------------------------------------------------------
 /*!	@defined	check_compile_time_code
diff --git a/mDNSShared/dns_sd.h b/mDNSShared/dns_sd.h
index 7632a22..911c70d 100644
--- a/mDNSShared/dns_sd.h
+++ b/mDNSShared/dns_sd.h
@@ -77,7 +77,7 @@
  */
 
 #ifndef _DNS_SD_H
-#define _DNS_SD_H 2581400
+#define _DNS_SD_H 2581800
 
 #ifdef  __cplusplus
     extern "C" {
diff --git a/mDNSShared/uds_daemon.c b/mDNSShared/uds_daemon.c
index aff5ff0..964667c 100644
--- a/mDNSShared/uds_daemon.c
+++ b/mDNSShared/uds_daemon.c
@@ -2040,7 +2040,7 @@
 
 	if (!request->msgptr) { LogMsg("%3d: DNSServiceBrowse(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
 
-	if (domain[0] == '\0') uDNS_RegisterSearchDomains(&mDNSStorage);
+	if (domain[0] == '\0') uDNS_SetupSearchDomains(&mDNSStorage, UDNS_START_WAB_QUERY);
 
 	typedn.c[0] = 0;
 	NumSubTypes = ChopSubTypes(regtype);	// Note: Modifies regtype string to remove trailing subtypes
@@ -2588,7 +2588,7 @@
 		{ LogMsg("%3d: DNSServiceEnumerateDomains(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
 
 	// allocate context structures
-	uDNS_RegisterSearchDomains(&mDNSStorage);
+	uDNS_SetupSearchDomains(&mDNSStorage, UDNS_START_WAB_QUERY);
 
 #if 0
 	// mark which kind of enumeration we're doing so we can (de)authorize certain domains
@@ -3832,6 +3832,8 @@
 	LogTimer("m->DelaySleep           ", m->DelaySleep);
 	LogTimer("m->SleepLimit           ", m->SleepLimit);
 	LogMsgNoIdent("m->RegisterAutoTunnel6  %08X", m->RegisterAutoTunnel6);
+	LogMsgNoIdent("m->AutoTunnelRelayAddrIn  %.16a", &m->AutoTunnelRelayAddrIn);
+	LogMsgNoIdent("m->AutoTunnelRelayAddrOut  %.16a", &m->AutoTunnelRelayAddrOut);
 	}
 
 #if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING