/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2002-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.
 * 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.

 * To Do:
 * Elimate all mDNSPlatformMemAllocate/mDNSPlatformMemFree from this code -- the core code
 * is supposed to be malloc-free so that it runs in constant memory determined at compile-time.
 * Any dynamic run-time requirements should be handled by the platform layer below or client layer above
 */

#include "uDNS.h"

#if(defined(_MSC_VER))
	// Disable "assignment within conditional expression".
	// Other compilers understand the convention that if you place the assignment expression within an extra pair
	// of parentheses, this signals to the compiler that you really intended an assignment and no warning is necessary.
	// The Microsoft compiler doesn't understand this convention, so in the absense of any other way to signal
	// to the compiler that the assignment is intentional, we have to just turn this warning off completely.
	#pragma warning(disable:4706)
#endif

// For domain enumeration and automatic browsing
// This is the user's DNS search list.
// In each of these domains we search for our special pointer records (lb._dns-sd._udp.<domain>, etc.)
// to discover recommended domains for domain enumeration (browse, default browse, registration,
// default registration) and possibly one or more recommended automatic browsing domains.
mDNSexport SearchListElem *SearchList = mDNSNULL;

// The value can be set to true by the Platform code e.g., MacOSX uses the plist mechanism
mDNSBool StrictUnicastOrdering = mDNSfalse;

// We keep track of the number of unicast DNS servers and log a message when we exceed 64.
// Currently the unicast queries maintain a 64 bit map to track the valid DNS servers for that
// question. Bit position is the index into the DNS server list. This is done so to try all
// the servers exactly once before giving up. If we could allocate memory in the core, then
// arbitrary limitation of 64 DNSServers can be removed.
mDNSu8 NumUnicastDNSServers = 0;
#define MAX_UNICAST_DNS_SERVERS	64

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - General Utility Functions
#endif

// set retry timestamp for record with exponential backoff
mDNSlocal void SetRecordRetry(mDNS *const m, AuthRecord *rr, mDNSu32 random)
	{
	rr->LastAPTime = m->timenow;

	if (rr->expire && rr->refreshCount < MAX_UPDATE_REFRESH_COUNT)
		{
		mDNSs32 remaining = rr->expire - m->timenow;
		rr->refreshCount++;
		if (remaining > MIN_UPDATE_REFRESH_TIME)
			{
			// Refresh at 70% + random (currently it is 0 to 10%)
			rr->ThisAPInterval =  7 * (remaining/10) + (random ? random : mDNSRandom(remaining/10));
			// Don't update more often than 5 minutes
			if (rr->ThisAPInterval < MIN_UPDATE_REFRESH_TIME)
				rr->ThisAPInterval = MIN_UPDATE_REFRESH_TIME;
			LogInfo("SetRecordRetry refresh in %d of %d for %s",
				rr->ThisAPInterval/mDNSPlatformOneSecond, (rr->expire - m->timenow)/mDNSPlatformOneSecond, ARDisplayString(m, rr));
			}
		else
			{
			rr->ThisAPInterval = MIN_UPDATE_REFRESH_TIME;
			LogInfo("SetRecordRetry clamping to min refresh in %d of %d for %s",
				rr->ThisAPInterval/mDNSPlatformOneSecond, (rr->expire - m->timenow)/mDNSPlatformOneSecond, ARDisplayString(m, rr));
			}
		return;
		}

	rr->expire = 0;

	rr->ThisAPInterval = rr->ThisAPInterval * QuestionIntervalStep;	// Same Retry logic as Unicast Queries
	if (rr->ThisAPInterval < INIT_RECORD_REG_INTERVAL)
		rr->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
	if (rr->ThisAPInterval > MAX_RECORD_REG_INTERVAL)
		rr->ThisAPInterval = MAX_RECORD_REG_INTERVAL;

	LogInfo("SetRecordRetry retry in %d ms for %s", rr->ThisAPInterval, ARDisplayString(m, rr));
	}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - Name Server List Management
#endif

mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSAddr *addr, const mDNSIPPort port, mDNSBool scoped)
	{
	DNSServer **p = &m->DNSServers;
	DNSServer *tmp = mDNSNULL;
	
	if ((NumUnicastDNSServers + 1) > MAX_UNICAST_DNS_SERVERS)
		{
		LogMsg("mDNS_AddDNSServer: DNS server limit of %d reached, not adding this server", MAX_UNICAST_DNS_SERVERS);
		return mDNSNULL;
		}

	if (!d) d = (const domainname *)"";

	LogInfo("mDNS_AddDNSServer: Adding %#a for %##s, InterfaceID %p, scoped %d", addr, d->c, interface, scoped);
	if (m->mDNS_busy != m->mDNS_reentrancy+1)
		LogMsg("mDNS_AddDNSServer: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);

	while (*p)	// Check if we already have this {interface,address,port,domain} tuple registered
		{
		if ((*p)->scoped == scoped && (*p)->interface == interface && (*p)->teststate != DNSServer_Disabled &&
			mDNSSameAddress(&(*p)->addr, addr) && mDNSSameIPPort((*p)->port, port) && SameDomainName(&(*p)->domain, d))
			{
			if (!((*p)->flags & DNSServer_FlagDelete)) debugf("Note: DNS Server %#a:%d for domain %##s (%p) registered more than once", addr, mDNSVal16(port), d->c, interface);
			(*p)->flags &= ~DNSServer_FlagDelete;
			tmp = *p;
			*p = tmp->next;
			tmp->next = mDNSNULL;
			}
		else
			p=&(*p)->next;
		}

	if (tmp) *p = tmp; // move to end of list, to ensure ordering from platform layer
	else
		{
		// allocate, add to list
		*p = mDNSPlatformMemAllocate(sizeof(**p));
		if (!*p) LogMsg("Error: mDNS_AddDNSServer - malloc");
		else
			{
			NumUnicastDNSServers++;
			(*p)->scoped	= scoped;
			(*p)->interface = interface;
			(*p)->addr      = *addr;
			(*p)->port      = port;
			(*p)->flags     = DNSServer_FlagNew;
			(*p)->teststate = /* DNSServer_Untested */ DNSServer_Passed;
			(*p)->lasttest  = m->timenow - INIT_UCAST_POLL_INTERVAL;
			AssignDomainName(&(*p)->domain, d);
			(*p)->next = mDNSNULL;
			}
		}
	(*p)->penaltyTime = 0;
	return(*p);
	}

// PenalizeDNSServer is called when the number of queries to the unicast
// DNS server exceeds MAX_UCAST_UNANSWERED_QUERIES or when we receive an
// error e.g., SERV_FAIL from DNS server.
mDNSexport void PenalizeDNSServer(mDNS *const m, DNSQuestion *q)
	{
	DNSServer *new;
	DNSServer *orig = q->qDNSServer;
	
	if (m->mDNS_busy != m->mDNS_reentrancy+1)
		LogMsg("PenalizeDNSServer: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);

	// This should never happen. Whenever we change DNS server, we change the ID on the question and hence
	// we should never accept a response after we penalize a DNS server e.g., send two queries, no response,
	// penalize DNS server and no new servers to pick for the question and hence qDNSServer is NULL. If we
	// receive a response now, the DNS server can be NULL. But we won't because the ID already has been
	// changed.
	if (!q->qDNSServer)
		{
		LogMsg("PenalizeDNSServer: ERROR!! Null DNS server for %##s (%s) %d", q->qname.c, DNSTypeName(q->qtype), q->unansweredQueries);
		goto end;
		}

	LogInfo("PenalizeDNSServer: Penalizing DNS server %#a:%d question (%##s) for question %p %##s (%s) SuppressUnusable %d",
		&q->qDNSServer->addr, mDNSVal16(q->qDNSServer->port), q->qDNSServer->domain.c, q, q->qname.c, DNSTypeName(q->qtype),
		q->SuppressUnusable);

	// If strict ordering of unicast servers needs to be preserved, we just lookup
	// the next best match server below
	//
	// If strict ordering is not required which is the default behavior, we penalize the server
	// for DNSSERVER_PENALTY_TIME. We may also use additional logic e.g., don't penalize for PTR
	// in the future.

	if (!StrictUnicastOrdering)
		{
		LogInfo("PenalizeDNSServer: Strict Unicast Ordering is FALSE");
		// We penalize the server so that new queries don't pick this server for DNSSERVER_PENALTY_TIME
		// XXX Include other logic here to see if this server should really be penalized
		//
		if (q->qtype == kDNSType_PTR)
			{
			LogInfo("PenalizeDNSServer: Not Penalizing PTR question");
			}
		else
			{
			LogInfo("PenalizeDNSServer: Penalizing question type %d", q->qtype);
			q->qDNSServer->penaltyTime = NonZeroTime(m->timenow + DNSSERVER_PENALTY_TIME);
			}
		}
	else
		{
		LogInfo("PenalizeDNSServer: Strict Unicast Ordering is TRUE");
		}

end:
	new = GetServerForQuestion(m, q);

	
	if (new == orig)
		{
		if (new)
			LogMsg("PenalizeDNSServer: ERROR!! GetServerForQuestion returned the same server %#a:%d", &new->addr, 
		    	mDNSVal16(new->port));
		else
			LogMsg("PenalizeDNSServer: ERROR!! GetServerForQuestion returned the same server NULL");
		q->ThisQInterval = 0;	// Inactivate this question so that we dont bombard the network
		}
	else
		{
		// The new DNSServer is set in DNSServerChangeForQuestion
		DNSServerChangeForQuestion(m, q, new);

		if (new)
			{
			LogInfo("PenalizeDNSServer: Server for %##s (%s) changed to %#a:%d (%##s)",
				q->qname.c, DNSTypeName(q->qtype), &q->qDNSServer->addr, mDNSVal16(q->qDNSServer->port), q->qDNSServer->domain.c);
			// We want to try the next server immediately. As the question may already have backed off, reset
			// the interval. We do this only the first time when we try all the DNS servers. Once we reached the end of
			// list and retrying all the servers again e.g., at least one server failed to respond in the previous try, we
			// use the normal backoff which is done in uDNS_CheckCurrentQuestion when we send the packet out.
			if (!q->triedAllServersOnce)
				{
				q->ThisQInterval = InitialQuestionInterval;
				q->LastQTime  = m->timenow - q->ThisQInterval;
				SetNextQueryTime(m, q);
				}
			}
		else
			{
			// We don't have any more DNS servers for this question. If some server in the list did not return
			// any response, we need to keep retrying till we get a response. uDNS_CheckCurrentQuestion handles
			// this case.
			//
			// If all servers responded with a negative response, We need to do two things. First, generate a
			// negative response so that applications get a reply. We also need to reinitialize the DNS servers
			// so that when the cache expires, we can restart the query. 
			//
			// Negative response may be generated in two ways.
			//
			// 1. AnswerQuestionForDNSServerChanges (called from DNSServerChangedForQuestion) might find some
			//    cache entries and answer this question.
			// 2. uDNS_CheckCurrentQuestion will create a new cache entry and answer this question
			//
			// For (1), it might be okay to reinitialize the DNS servers here. But for (2), we can't do it here
			// because uDNS_CheckCurrentQuestion will try resending the queries. Hence, to be consistent, we
			// defer reintializing the DNS servers up until generating a negative cache response.
			//
			// Be careful not to touch the ThisQInterval here. For a normal question, when we answer the question
			// in AnswerCurrentQuestionWithResourceRecord will set ThisQInterval to MaxQuestionInterval and hence
			// the next query will not happen until cache expiry. If it is a long lived question,
			// AnswerCurrentQuestionWithResourceRecord will not set it to MaxQuestionInterval. In that case,
			// we want the normal backoff to work.
			LogInfo("PenalizeDNSServer: Server for %p, %##s (%s) changed to NULL, Interval %d", q, q->qname.c, DNSTypeName(q->qtype), q->ThisQInterval);
			}
		q->unansweredQueries = 0;

		}
	}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - authorization management
#endif

mDNSlocal DomainAuthInfo *GetAuthInfoForName_direct(mDNS *m, const domainname *const name)
	{
	const domainname *n = name;
	while (n->c[0])
		{
		DomainAuthInfo *ptr;
		for (ptr = m->AuthInfoList; ptr; ptr = ptr->next)
			if (SameDomainName(&ptr->domain, n))
				{
				debugf("GetAuthInfoForName %##s Matched %##s Key name %##s", name->c, ptr->domain.c, ptr->keyname.c);
				return(ptr);
				}
		n = (const domainname *)(n->c + 1 + n->c[0]);
		}
	//LogInfo("GetAuthInfoForName none found for %##s", name->c);
	return mDNSNULL;
	}

// MUST be called with lock held
mDNSexport DomainAuthInfo *GetAuthInfoForName_internal(mDNS *m, const domainname *const name)
	{
	DomainAuthInfo **p = &m->AuthInfoList;

	if (m->mDNS_busy != m->mDNS_reentrancy+1)
		LogMsg("GetAuthInfoForName_internal: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);

	// First purge any dead keys from the list
	while (*p)
		{
		if ((*p)->deltime && m->timenow - (*p)->deltime >= 0 && AutoTunnelUnregistered(*p))
			{
			DNSQuestion *q;
			DomainAuthInfo *info = *p;
			LogInfo("GetAuthInfoForName_internal deleting expired key %##s %##s", info->domain.c, info->keyname.c);
			*p = info->next;	// Cut DomainAuthInfo from list *before* scanning our question list updating AuthInfo pointers
			for (q = m->Questions; q; q=q->next)
				if (q->AuthInfo == info)
					{
					q->AuthInfo = GetAuthInfoForName_direct(m, &q->qname);
					debugf("GetAuthInfoForName_internal updated q->AuthInfo from %##s to %##s for %##s (%s)",
						info->domain.c, q->AuthInfo ? q->AuthInfo->domain.c : mDNSNULL, q->qname.c, DNSTypeName(q->qtype));
					}

			// Probably not essential, but just to be safe, zero out the secret key data
			// so we don't leave it hanging around in memory
			// (where it could potentially get exposed via some other bug)
			mDNSPlatformMemZero(info, sizeof(*info));
			mDNSPlatformMemFree(info);
			}
		else
			p = &(*p)->next;
		}

	return(GetAuthInfoForName_direct(m, name));
	}

mDNSexport DomainAuthInfo *GetAuthInfoForName(mDNS *m, const domainname *const name)
	{
	DomainAuthInfo *d;
	mDNS_Lock(m);
	d = GetAuthInfoForName_internal(m, name);
	mDNS_Unlock(m);
	return(d);
	}

// MUST be called with the lock held
mDNSexport mStatus mDNS_SetSecretForDomain(mDNS *m, DomainAuthInfo *info,
	const domainname *domain, const domainname *keyname, const char *b64keydata, mDNSBool AutoTunnel)
	{
	DNSQuestion *q;
	DomainAuthInfo **p = &m->AuthInfoList;
	if (!info || !b64keydata) { LogMsg("mDNS_SetSecretForDomain: ERROR: info %p b64keydata %p", info, b64keydata); return(mStatus_BadParamErr); }

	LogInfo("mDNS_SetSecretForDomain: domain %##s key %##s%s", domain->c, keyname->c, AutoTunnel ? " AutoTunnel" : "");

	info->AutoTunnel = AutoTunnel;
	AssignDomainName(&info->domain,  domain);
	AssignDomainName(&info->keyname, keyname);
	mDNS_snprintf(info->b64keydata, sizeof(info->b64keydata), "%s", b64keydata);

	if (DNSDigest_ConstructHMACKeyfromBase64(info, b64keydata) < 0)
		{
		LogMsg("mDNS_SetSecretForDomain: ERROR: Could not convert shared secret from base64: domain %##s key %##s %s", domain->c, keyname->c, mDNS_LoggingEnabled ? b64keydata : "");
		return(mStatus_BadParamErr);
		}

	// Don't clear deltime until after we've ascertained that b64keydata is valid
	info->deltime = 0;

	while (*p && (*p) != info) p=&(*p)->next;
	if (*p) {LogInfo("mDNS_SetSecretForDomain: Domain %##s Already in list", (*p)->domain.c); return(mStatus_AlreadyRegistered);}

	// Caution: Only zero AutoTunnelHostRecord.namestorage and AutoTunnelNAT.clientContext AFTER we've determined that this is a NEW DomainAuthInfo
	// being added to the list. Otherwise we risk smashing our AutoTunnel host records and NATOperation that are already active and in use.
	info->AutoTunnelHostRecord.resrec.RecordType = kDNSRecordTypeUnregistered;
	info->AutoTunnelHostRecord.namestorage.c[0] = 0;
	info->AutoTunnelTarget    .resrec.RecordType = kDNSRecordTypeUnregistered;
	info->AutoTunnelDeviceInfo.resrec.RecordType = kDNSRecordTypeUnregistered;
	info->AutoTunnelService   .resrec.RecordType = kDNSRecordTypeUnregistered;
	info->AutoTunnel6Record   .resrec.RecordType = kDNSRecordTypeUnregistered;
	info->AutoTunnelNAT.clientContext = mDNSNULL;
	info->next = mDNSNULL;
	*p = info;

	// Check to see if adding this new DomainAuthInfo has changed the credentials for any of our questions
	for (q = m->Questions; q; q=q->next)
		{
		DomainAuthInfo *newinfo = GetAuthInfoForQuestion(m, q);
		if (q->AuthInfo != newinfo)
			{
			debugf("mDNS_SetSecretForDomain updating q->AuthInfo from %##s to %##s for %##s (%s)",
				q->AuthInfo ? q->AuthInfo->domain.c : mDNSNULL,
				newinfo     ? newinfo    ->domain.c : mDNSNULL, q->qname.c, DNSTypeName(q->qtype));
			q->AuthInfo = newinfo;
			}
		}

	return(mStatus_NoError);
	}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - NAT Traversal
#endif

mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info)
	{
	mStatus err = mStatus_NoError;

	// send msg if we have a router and it is a private address
	if (!mDNSIPv4AddressIsZero(m->Router.ip.v4) && mDNSv4AddrIsRFC1918(&m->Router.ip.v4))
		{
		union { NATAddrRequest NATAddrReq; NATPortMapRequest NATPortReq; } u = { { NATMAP_VERS, NATOp_AddrRequest } } ;
		const mDNSu8 *end = (mDNSu8 *)&u + sizeof(NATAddrRequest);
	
		if (info)			// For NATOp_MapUDP and NATOp_MapTCP, fill in additional fields
			{
			mDNSu8 *p = (mDNSu8 *)&u.NATPortReq.NATReq_lease;
			u.NATPortReq.opcode  = info->Protocol;
			u.NATPortReq.unused  = zeroID;
			u.NATPortReq.intport = info->IntPort;
			u.NATPortReq.extport = info->RequestedPort;
			p[0] = (mDNSu8)((info->NATLease >> 24) &  0xFF);
			p[1] = (mDNSu8)((info->NATLease >> 16) &  0xFF);
			p[2] = (mDNSu8)((info->NATLease >>  8) &  0xFF);
			p[3] = (mDNSu8)( info->NATLease        &  0xFF);
			end = (mDNSu8 *)&u + sizeof(NATPortMapRequest);
			}

		err = mDNSPlatformSendUDP(m, (mDNSu8 *)&u, end, 0, mDNSNULL, &m->Router, NATPMPPort);

#ifdef _LEGACY_NAT_TRAVERSAL_
		if (mDNSIPPortIsZero(m->UPnPRouterPort) || mDNSIPPortIsZero(m->UPnPSOAPPort)) LNT_SendDiscoveryMsg(m);
		else if (info) err = LNT_MapPort(m, info);
		else err = LNT_GetExternalAddress(m);
#endif // _LEGACY_NAT_TRAVERSAL_
		}
	return(err);
	}

mDNSexport void RecreateNATMappings(mDNS *const m)
	{
	NATTraversalInfo *n;
	for (n = m->NATTraversals; n; n=n->next)
		{
		n->ExpiryTime    = 0;		// Mark this mapping as expired
		n->retryInterval = NATMAP_INIT_RETRY;
		n->retryPortMap  = m->timenow;
#ifdef _LEGACY_NAT_TRAVERSAL_
		if (n->tcpInfo.sock) { mDNSPlatformTCPCloseConnection(n->tcpInfo.sock); n->tcpInfo.sock = mDNSNULL; }
#endif // _LEGACY_NAT_TRAVERSAL_
		}

	m->NextScheduledNATOp = m->timenow;		// Need to send packets immediately
	}

mDNSexport void natTraversalHandleAddressReply(mDNS *const m, mDNSu16 err, mDNSv4Addr ExtAddr)
	{
	static mDNSu16 last_err = 0;
	
	if (err)
		{
		if (err != last_err) LogMsg("Error getting external address %d", err);
		ExtAddr = zerov4Addr;
		}
	else
		{
		LogInfo("Received external IP address %.4a from NAT", &ExtAddr);
		if (mDNSv4AddrIsRFC1918(&ExtAddr))
			LogMsg("Double NAT (external NAT gateway address %.4a is also a private RFC 1918 address)", &ExtAddr);
		if (mDNSIPv4AddressIsZero(ExtAddr))
			err = NATErr_NetFail; // fake error to handle routers that pathologically report success with the zero address
		}
		
	if (!mDNSSameIPv4Address(m->ExternalAddress, ExtAddr))
		{
		m->ExternalAddress = ExtAddr;
		RecreateNATMappings(m);		// Also sets NextScheduledNATOp for us
		}

	if (!err) // Success, back-off to maximum interval
		m->retryIntervalGetAddr = NATMAP_MAX_RETRY_INTERVAL;
	else if (!last_err) // Failure after success, retry quickly (then back-off exponentially)
		m->retryIntervalGetAddr = NATMAP_INIT_RETRY;
	// else back-off normally in case of pathological failures

	m->retryGetAddr = m->timenow + m->retryIntervalGetAddr;
	if (m->NextScheduledNATOp - m->retryIntervalGetAddr > 0)
		m->NextScheduledNATOp = m->retryIntervalGetAddr;

	last_err = err;
	}

// Both places that call NATSetNextRenewalTime() update m->NextScheduledNATOp correctly afterwards
mDNSlocal void NATSetNextRenewalTime(mDNS *const m, NATTraversalInfo *n)
	{
	n->retryInterval = (n->ExpiryTime - m->timenow)/2;
	if (n->retryInterval < NATMAP_MIN_RETRY_INTERVAL)	// Min retry interval is 2 seconds
		n->retryInterval = NATMAP_MIN_RETRY_INTERVAL;
	n->retryPortMap = m->timenow + n->retryInterval;
	}

// Note: When called from handleLNTPortMappingResponse() only pkt->err, pkt->extport and pkt->NATRep_lease fields are filled in
mDNSexport void natTraversalHandlePortMapReply(mDNS *const m, NATTraversalInfo *n, const mDNSInterfaceID InterfaceID, mDNSu16 err, mDNSIPPort extport, mDNSu32 lease)
	{
	const char *prot = n->Protocol == NATOp_MapUDP ? "UDP" : n->Protocol == NATOp_MapTCP ? "TCP" : "?";
	(void)prot;
	n->NewResult = err;
	if (err || lease == 0 || mDNSIPPortIsZero(extport))
		{
		LogInfo("natTraversalHandlePortMapReply: %p Response %s Port %5d External Port %5d lease %d error %d",
			n, prot, mDNSVal16(n->IntPort), mDNSVal16(extport), lease, err);
		n->retryInterval = NATMAP_MAX_RETRY_INTERVAL;
		n->retryPortMap = m->timenow + NATMAP_MAX_RETRY_INTERVAL;
		// No need to set m->NextScheduledNATOp here, since we're only ever extending the m->retryPortMap time
		if      (err == NATErr_Refused)                     n->NewResult = mStatus_NATPortMappingDisabled;
		else if (err > NATErr_None && err <= NATErr_Opcode) n->NewResult = mStatus_NATPortMappingUnsupported;
		}
	else
		{
		if (lease > 999999999UL / mDNSPlatformOneSecond)
			lease = 999999999UL / mDNSPlatformOneSecond;
		n->ExpiryTime = NonZeroTime(m->timenow + lease * mDNSPlatformOneSecond);
	
		if (!mDNSSameIPPort(n->RequestedPort, extport))
			LogInfo("natTraversalHandlePortMapReply: %p Response %s Port %5d External Port %5d changed to %5d",
				n, prot, mDNSVal16(n->IntPort), mDNSVal16(n->RequestedPort), mDNSVal16(extport));

		n->InterfaceID   = InterfaceID;
		n->RequestedPort = extport;
	
		LogInfo("natTraversalHandlePortMapReply: %p Response %s Port %5d External Port %5d lease %d",
			n, prot, mDNSVal16(n->IntPort), mDNSVal16(extport), lease);
	
		NATSetNextRenewalTime(m, n);			// Got our port mapping; now set timer to renew it at halfway point
		m->NextScheduledNATOp = m->timenow;		// May need to invoke client callback immediately
		}
	}

// Must be called with the mDNS_Lock held
mDNSexport mStatus mDNS_StartNATOperation_internal(mDNS *const m, NATTraversalInfo *traversal)
	{
	NATTraversalInfo **n;
	
	LogInfo("mDNS_StartNATOperation_internal %p Protocol %d IntPort %d RequestedPort %d NATLease %d", traversal,
		traversal->Protocol, mDNSVal16(traversal->IntPort), mDNSVal16(traversal->RequestedPort), traversal->NATLease);

	// Note: It important that new traversal requests are appended at the *end* of the list, not prepended at the start
	for (n = &m->NATTraversals; *n; n=&(*n)->next)
		{
		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",
				traversal, traversal->Protocol, mDNSVal16(traversal->IntPort), traversal->NATLease);
			return(mStatus_AlreadyRegistered);
			}
		if (traversal->Protocol && traversal->Protocol == (*n)->Protocol && mDNSSameIPPort(traversal->IntPort, (*n)->IntPort) &&
			!mDNSSameIPPort(traversal->IntPort, SSHPort))
			LogMsg("Warning: Created port mapping request %p Prot %d Int %d TTL %d "
				"duplicates existing port mapping request %p Prot %d Int %d TTL %d",
				traversal, traversal->Protocol, mDNSVal16(traversal->IntPort), traversal->NATLease,
				*n,        (*n)     ->Protocol, mDNSVal16((*n)     ->IntPort), (*n)     ->NATLease);
		}

	// Initialize necessary fields
	traversal->next            = mDNSNULL;
	traversal->ExpiryTime      = 0;
	traversal->retryInterval   = NATMAP_INIT_RETRY;
	traversal->retryPortMap    = m->timenow;
	traversal->NewResult       = mStatus_NoError;
	traversal->ExternalAddress = onesIPv4Addr;
	traversal->ExternalPort    = zeroIPPort;
	traversal->Lifetime        = 0;
	traversal->Result          = mStatus_NoError;

	// set default lease if necessary
	if (!traversal->NATLease) traversal->NATLease = NATMAP_DEFAULT_LEASE;

#ifdef _LEGACY_NAT_TRAVERSAL_
	mDNSPlatformMemZero(&traversal->tcpInfo, sizeof(traversal->tcpInfo));
#endif // _LEGACY_NAT_TRAVERSAL_

	if (!m->NATTraversals)		// If this is our first NAT request, kick off an address request too
		{
		m->retryGetAddr         = m->timenow;
		m->retryIntervalGetAddr = NATMAP_INIT_RETRY;
		}

	m->NextScheduledNATOp = m->timenow;	// This will always trigger sending the packet ASAP, and generate client callback if necessary

	*n = traversal;		// Append new NATTraversalInfo to the end of our list

	return(mStatus_NoError);
	}

// Must be called with the mDNS_Lock held
mDNSexport mStatus mDNS_StopNATOperation_internal(mDNS *m, NATTraversalInfo *traversal)
	{
	mDNSBool unmap = mDNStrue;
	NATTraversalInfo *p;
	NATTraversalInfo **ptr = &m->NATTraversals;

	while (*ptr && *ptr != traversal) ptr=&(*ptr)->next;
	if (*ptr) *ptr = (*ptr)->next;		// If we found it, cut this NATTraversalInfo struct from our list
	else
		{
		LogMsg("mDNS_StopNATOperation_internal: NATTraversalInfo %p not found in list", traversal);
		return(mStatus_BadReferenceErr);
		}

	LogInfo("mDNS_StopNATOperation_internal %p %d %d %d %d", traversal,
		traversal->Protocol, mDNSVal16(traversal->IntPort), mDNSVal16(traversal->RequestedPort), traversal->NATLease);

	if (m->CurrentNATTraversal == traversal)
		m->CurrentNATTraversal = m->CurrentNATTraversal->next;

	if (traversal->Protocol)
		for (p = m->NATTraversals; p; p=p->next)
			if (traversal->Protocol == p->Protocol && mDNSSameIPPort(traversal->IntPort, p->IntPort))
				{
				if (!mDNSSameIPPort(traversal->IntPort, SSHPort))
					LogMsg("Warning: Removed port mapping request %p Prot %d Int %d TTL %d "
						"duplicates existing port mapping request %p Prot %d Int %d TTL %d",
						traversal, traversal->Protocol, mDNSVal16(traversal->IntPort), traversal->NATLease,
						p,         p        ->Protocol, mDNSVal16(p        ->IntPort), p        ->NATLease);
				unmap = mDNSfalse;
				}

	if (traversal->ExpiryTime && unmap)
		{
		traversal->NATLease = 0;
		traversal->retryInterval = 0;
		uDNS_SendNATMsg(m, traversal);
		}

	// Even if we DIDN'T make a successful UPnP mapping yet, we might still have a partially-open TCP connection we need to clean up
	#ifdef _LEGACY_NAT_TRAVERSAL_
		{
		mStatus err = LNT_UnmapPort(m, traversal);
		if (err) LogMsg("Legacy NAT Traversal - unmap request failed with error %d", err);
		}
	#endif // _LEGACY_NAT_TRAVERSAL_

	return(mStatus_NoError);
	}

mDNSexport mStatus mDNS_StartNATOperation(mDNS *const m, NATTraversalInfo *traversal)
	{
	mStatus status;
	mDNS_Lock(m);
	status = mDNS_StartNATOperation_internal(m, traversal);
	mDNS_Unlock(m);
	return(status);
	}

mDNSexport mStatus mDNS_StopNATOperation(mDNS *const m, NATTraversalInfo *traversal)
	{
	mStatus status;
	mDNS_Lock(m);
	status = mDNS_StopNATOperation_internal(m, traversal);
	mDNS_Unlock(m);
	return(status);
	}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - Long-Lived Queries
#endif

// Lock must be held -- otherwise m->timenow is undefined
mDNSlocal void StartLLQPolling(mDNS *const m, DNSQuestion *q)
	{
	debugf("StartLLQPolling: %##s", q->qname.c);
	q->state = LLQ_Poll;
	q->ThisQInterval = INIT_UCAST_POLL_INTERVAL;
	// We want to send our poll query ASAP, but the "+ 1" is because if we set the time to now,
	// we risk causing spurious "SendQueries didn't send all its queries" log messages
	q->LastQTime     = m->timenow - q->ThisQInterval + 1;
	SetNextQueryTime(m, q);
#if APPLE_OSX_mDNSResponder
	UpdateAutoTunnelDomainStatuses(m);
#endif
	}

mDNSlocal mDNSu8 *putLLQ(DNSMessage *const msg, mDNSu8 *ptr, const DNSQuestion *const question, const LLQOptData *const data)
	{
	AuthRecord rr;
	ResourceRecord *opt = &rr.resrec;
	rdataOPT *optRD;

	//!!!KRS when we implement multiple llqs per message, we'll need to memmove anything past the question section
	ptr = putQuestion(msg, ptr, msg->data + AbsoluteMaxDNSMessageData, &question->qname, question->qtype, question->qclass);
	if (!ptr) { LogMsg("ERROR: putLLQ - putQuestion"); return mDNSNULL; }

	// locate OptRR if it exists, set pointer to end
	// !!!KRS implement me

	// format opt rr (fields not specified are zero-valued)
	mDNS_SetupResourceRecord(&rr, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, mDNSNULL, mDNSNULL);
	opt->rrclass    = NormalMaxDNSMessageData;
	opt->rdlength   = sizeof(rdataOPT);	// One option in this OPT record
	opt->rdestimate = sizeof(rdataOPT);

	optRD = &rr.resrec.rdata->u.opt[0];
	optRD->opt = kDNSOpt_LLQ;
	optRD->u.llq = *data;
	ptr = PutResourceRecordTTLJumbo(msg, ptr, &msg->h.numAdditionals, opt, 0);
	if (!ptr) { LogMsg("ERROR: putLLQ - PutResourceRecordTTLJumbo"); return mDNSNULL; }

	return ptr;
	}

// Normally we'd just request event packets be sent directly to m->LLQNAT.ExternalPort, except...
// with LLQs over TLS/TCP we're doing a weird thing where instead of requesting packets be sent to ExternalAddress:ExternalPort
// we're requesting that packets be sent to ExternalPort, but at the source address of our outgoing TCP connection.
// Normally, after going through the NAT gateway, the source address of our outgoing TCP connection is the same as ExternalAddress,
// so this is fine, except when the TCP connection ends up going over a VPN tunnel instead.
// To work around this, if we find that the source address for our TCP connection is not a private address, we tell the Dot Mac
// LLQ server to send events to us directly at port 5353 on that address, instead of at our mapped external NAT port.

mDNSlocal mDNSu16 GetLLQEventPort(const mDNS *const m, const mDNSAddr *const dst)
	{
	mDNSAddr src;
	mDNSPlatformSourceAddrForDest(&src, dst);
	//LogMsg("GetLLQEventPort: src %#a for dst %#a (%d)", &src, dst, mDNSv4AddrIsRFC1918(&src.ip.v4) ? mDNSVal16(m->LLQNAT.ExternalPort) : 0);
	return(mDNSv4AddrIsRFC1918(&src.ip.v4) ? mDNSVal16(m->LLQNAT.ExternalPort) : mDNSVal16(MulticastDNSPort));
	}

// Normally called with llq set.
// May be called with llq NULL, when retransmitting a lost Challenge Response
mDNSlocal void sendChallengeResponse(mDNS *const m, DNSQuestion *const q, const LLQOptData *llq)
	{
	mDNSu8 *responsePtr = m->omsg.data;
	LLQOptData llqBuf;

	if (q->tcp) { LogMsg("sendChallengeResponse: ERROR!!: question %##s (%s) tcp non-NULL", q->qname.c, DNSTypeName(q->qtype)); return; }

	if (PrivateQuery(q)) { LogMsg("sendChallengeResponse: ERROR!!: Private Query %##s (%s)", q->qname.c, DNSTypeName(q->qtype)); return; }

	if (q->ntries++ == kLLQ_MAX_TRIES)
		{
		LogMsg("sendChallengeResponse: %d failed attempts for LLQ %##s", kLLQ_MAX_TRIES, q->qname.c);
		StartLLQPolling(m,q);
		return;
		}

	if (!llq)		// Retransmission: need to make a new LLQOptData
		{
		llqBuf.vers     = kLLQ_Vers;
		llqBuf.llqOp    = kLLQOp_Setup;
		llqBuf.err      = LLQErr_NoError;	// Don't need to tell server UDP notification port when sending over UDP
		llqBuf.id       = q->id;
		llqBuf.llqlease = q->ReqLease;
		llq = &llqBuf;
		}

	q->LastQTime     = m->timenow;
	q->ThisQInterval = q->tcp ? 0 : (kLLQ_INIT_RESEND * q->ntries * mDNSPlatformOneSecond);		// If using TCP, don't need to retransmit
	SetNextQueryTime(m, q);

	// To simulate loss of challenge response packet, uncomment line below
	//if (q->ntries == 1) return;

	InitializeDNSMessage(&m->omsg.h, q->TargetQID, uQueryFlags);
	responsePtr = putLLQ(&m->omsg, responsePtr, q, llq);
	if (responsePtr)
		{
		mStatus err = mDNSSendDNSMessage(m, &m->omsg, responsePtr, mDNSInterface_Any, q->LocalSocket, &q->servAddr, q->servPort, mDNSNULL, mDNSNULL);
		if (err) { LogMsg("sendChallengeResponse: mDNSSendDNSMessage%s failed: %d", q->tcp ? " (TCP)" : "", err); }
		}
	else StartLLQPolling(m,q);
	}

mDNSlocal void SetLLQTimer(mDNS *const m, DNSQuestion *const q, const LLQOptData *const llq)
	{
	mDNSs32 lease = (mDNSs32)llq->llqlease * mDNSPlatformOneSecond;
	q->ReqLease      = llq->llqlease;
	q->LastQTime     = m->timenow;
	q->expire        = m->timenow + lease;
	q->ThisQInterval = lease/2 + mDNSRandom(lease/10);
	debugf("SetLLQTimer setting %##s (%s) to %d %d", q->qname.c, DNSTypeName(q->qtype), lease/mDNSPlatformOneSecond, q->ThisQInterval/mDNSPlatformOneSecond);
	SetNextQueryTime(m, q);
	}

mDNSlocal void recvSetupResponse(mDNS *const m, mDNSu8 rcode, DNSQuestion *const q, const LLQOptData *const llq)
	{
	if (rcode && rcode != kDNSFlag1_RC_NXDomain)
		{ LogMsg("ERROR: recvSetupResponse %##s (%s) - rcode && rcode != kDNSFlag1_RC_NXDomain", q->qname.c, DNSTypeName(q->qtype)); return; }

	if (llq->llqOp != kLLQOp_Setup)
		{ LogMsg("ERROR: recvSetupResponse %##s (%s) - bad op %d", q->qname.c, DNSTypeName(q->qtype), llq->llqOp); return; }

	if (llq->vers != kLLQ_Vers)
		{ LogMsg("ERROR: recvSetupResponse %##s (%s) - bad vers %d", q->qname.c, DNSTypeName(q->qtype), llq->vers); return; }

	if (q->state == LLQ_InitialRequest)
		{
		//LogInfo("Got LLQ_InitialRequest");

		if (llq->err) { LogMsg("recvSetupResponse - received llq->err %d from server", llq->err); StartLLQPolling(m,q); return; }
	
		if (q->ReqLease != llq->llqlease)
			debugf("recvSetupResponse: requested lease %lu, granted lease %lu", q->ReqLease, llq->llqlease);
	
		// cache expiration in case we go to sleep before finishing setup
		q->ReqLease = llq->llqlease;
		q->expire = m->timenow + ((mDNSs32)llq->llqlease * mDNSPlatformOneSecond);
	
		// update state
		q->state  = LLQ_SecondaryRequest;
		q->id     = llq->id;
		q->ntries = 0; // first attempt to send response
		sendChallengeResponse(m, q, llq);
		}
	else if (q->state == LLQ_SecondaryRequest)
		{
		//LogInfo("Got LLQ_SecondaryRequest");

		// Fix this immediately if not sooner.  Copy the id from the LLQOptData into our DNSQuestion struct.  This is only
		// an issue for private LLQs, because we skip parts 2 and 3 of the handshake.  This is related to a bigger
		// problem of the current implementation of TCP LLQ setup: we're not handling state transitions correctly
		// if the server sends back SERVFULL or STATIC.
		if (PrivateQuery(q))
			{
			LogInfo("Private LLQ_SecondaryRequest; copying id %08X%08X", llq->id.l[0], llq->id.l[1]);
			q->id = llq->id;
			}

		if (llq->err) { LogMsg("ERROR: recvSetupResponse %##s (%s) code %d from server", q->qname.c, DNSTypeName(q->qtype), llq->err); StartLLQPolling(m,q); return; }
		if (!mDNSSameOpaque64(&q->id, &llq->id))
			{ LogMsg("recvSetupResponse - ID changed.  discarding"); return; } // this can happen rarely (on packet loss + reordering)
		q->state         = LLQ_Established;
		q->ntries        = 0;
		SetLLQTimer(m, q, llq);
#if APPLE_OSX_mDNSResponder
		UpdateAutoTunnelDomainStatuses(m);
#endif
		}
	}

mDNSexport uDNS_LLQType uDNS_recvLLQResponse(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end,
	const mDNSAddr *const srcaddr, const mDNSIPPort srcport, DNSQuestion **matchQuestion)
	{
	DNSQuestion pktQ, *q;
	if (msg->h.numQuestions && getQuestion(msg, msg->data, end, 0, &pktQ))
		{
		const rdataOPT *opt = GetLLQOptData(m, msg, end);

		for (q = m->Questions; q; q = q->next)
			{
			if (!mDNSOpaque16IsZero(q->TargetQID) && q->LongLived && q->qtype == pktQ.qtype && q->qnamehash == pktQ.qnamehash && SameDomainName(&q->qname, &pktQ.qname))
				{
				debugf("uDNS_recvLLQResponse found %##s (%s) %d %#a %#a %X %X %X %X %d",
					q->qname.c, DNSTypeName(q->qtype), q->state, srcaddr, &q->servAddr,
					opt ? opt->u.llq.id.l[0] : 0, opt ? opt->u.llq.id.l[1] : 0, q->id.l[0], q->id.l[1], opt ? opt->u.llq.llqOp : 0);
				if (q->state == LLQ_Poll) debugf("uDNS_LLQ_Events: q->state == LLQ_Poll msg->h.id %d q->TargetQID %d", mDNSVal16(msg->h.id), mDNSVal16(q->TargetQID));
				if (q->state == LLQ_Poll && mDNSSameOpaque16(msg->h.id, q->TargetQID))
					{
					m->rec.r.resrec.RecordType = 0;		// Clear RecordType to show we're not still using it
					
					// Don't reset the state to IntialRequest as we may write that to the dynamic store
					// and PrefPane might wrongly think that we are "Starting" instead of "Polling". If
					// we are in polling state because of NAT-PMP disabled or DoubleNAT, next LLQNATCallback
					// would kick us back to LLQInitialRequest. So, resetting the state here may not be useful.
					//
					// If we have a good NAT (neither NAT-PMP disabled nor Double-NAT), then we should not be
					// possibly in polling state. To be safe, we want to retry from the start in that case
					// as there may not be another LLQNATCallback
					//
					// NOTE: We can be in polling state if we cannot resolve the SOA record i.e, servAddr is set to
					// all ones. In that case, we would set it in LLQ_InitialRequest as it overrides the NAT-PMP or
					// Double-NAT state.
					if (!mDNSAddressIsOnes(&q->servAddr) && !mDNSIPPortIsZero(m->LLQNAT.ExternalPort) &&
						!m->LLQNAT.Result)
						{
						debugf("uDNS_recvLLQResponse got poll response; moving to LLQ_InitialRequest for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
						q->state         = LLQ_InitialRequest;
						}
					q->servPort      = zeroIPPort;		// Clear servPort so that startLLQHandshake will retry the GetZoneData processing
					q->ThisQInterval = LLQ_POLL_INTERVAL + mDNSRandom(LLQ_POLL_INTERVAL/10);	// Retry LLQ setup in approx 15 minutes
					q->LastQTime     = m->timenow;
					SetNextQueryTime(m, q);
					*matchQuestion = q;
					return uDNS_LLQ_Entire;		// uDNS_LLQ_Entire means flush stale records; assume a large effective TTL
					}
				// Note: In LLQ Event packets, the msg->h.id does not match our q->TargetQID, because in that case the msg->h.id nonce is selected by the server
				else if (opt && q->state == LLQ_Established && opt->u.llq.llqOp == kLLQOp_Event && mDNSSameOpaque64(&opt->u.llq.id, &q->id))
					{
					mDNSu8 *ackEnd;
					//debugf("Sending LLQ ack for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
					InitializeDNSMessage(&m->omsg.h, msg->h.id, ResponseFlags);
					ackEnd = putLLQ(&m->omsg, m->omsg.data, q, &opt->u.llq);
					if (ackEnd) mDNSSendDNSMessage(m, &m->omsg, ackEnd, mDNSInterface_Any, q->LocalSocket, srcaddr, srcport, mDNSNULL, mDNSNULL);
					m->rec.r.resrec.RecordType = 0;		// Clear RecordType to show we're not still using it
					debugf("uDNS_LLQ_Events: q->state == LLQ_Established msg->h.id %d q->TargetQID %d", mDNSVal16(msg->h.id), mDNSVal16(q->TargetQID));
					*matchQuestion = q;
					return uDNS_LLQ_Events;
					}
				if (opt && mDNSSameOpaque16(msg->h.id, q->TargetQID))
					{
					if (q->state == LLQ_Established && opt->u.llq.llqOp == kLLQOp_Refresh && mDNSSameOpaque64(&opt->u.llq.id, &q->id) && msg->h.numAdditionals && !msg->h.numAnswers)
						{
						if (opt->u.llq.err != LLQErr_NoError) LogMsg("recvRefreshReply: received error %d from server", opt->u.llq.err);
						else
							{
							//LogInfo("Received refresh confirmation ntries %d for %##s (%s)", q->ntries, q->qname.c, DNSTypeName(q->qtype));
							// If we're waiting to go to sleep, then this LLQ deletion may have been the thing
							// we were waiting for, so schedule another check to see if we can sleep now.
							if (opt->u.llq.llqlease == 0 && m->SleepLimit) m->NextScheduledSPRetry = m->timenow;
							GrantCacheExtensions(m, q, opt->u.llq.llqlease);
							SetLLQTimer(m, q, &opt->u.llq);
							q->ntries = 0;
							}
						m->rec.r.resrec.RecordType = 0;		// Clear RecordType to show we're not still using it
						*matchQuestion = q;
						return uDNS_LLQ_Ignore;
						}
					if (q->state < LLQ_Established && mDNSSameAddress(srcaddr, &q->servAddr))
						{
						LLQ_State oldstate = q->state;
						recvSetupResponse(m, msg->h.flags.b[1] & kDNSFlag1_RC_Mask, q, &opt->u.llq);
						m->rec.r.resrec.RecordType = 0;		// Clear RecordType to show we're not still using it
						// We have a protocol anomaly here in the LLQ definition.
						// Both the challenge packet from the server and the ack+answers packet have opt->u.llq.llqOp == kLLQOp_Setup.
						// However, we need to treat them differently:
						// The challenge packet has no answers in it, and tells us nothing about whether our cache entries
						// are still valid, so this packet should not cause us to do anything that messes with our cache.
						// The ack+answers packet gives us the whole truth, so we should handle it by updating our cache
						// to match the answers in the packet, and only the answers in the packet.
						*matchQuestion = q;
						return (oldstate == LLQ_SecondaryRequest ? uDNS_LLQ_Entire : uDNS_LLQ_Ignore);
						}
					}
				}
			}
		m->rec.r.resrec.RecordType = 0;		// Clear RecordType to show we're not still using it
		}
	*matchQuestion = mDNSNULL;
	return uDNS_LLQ_Not;
	}

// Stub definition of TCPSocket_struct so we can access flags field. (Rest of TCPSocket_struct is platform-dependent.)
struct TCPSocket_struct { TCPSocketFlags flags; /* ... */ };

// tcpCallback is called to handle events (e.g. connection opening and data reception) on TCP connections for
// Private DNS operations -- private queries, private LLQs, private record updates and private service updates
mDNSlocal void tcpCallback(TCPSocket *sock, void *context, mDNSBool ConnectionEstablished, mStatus err)
	{
	tcpInfo_t *tcpInfo = (tcpInfo_t *)context;
	mDNSBool   closed  = mDNSfalse;
	mDNS      *m       = tcpInfo->m;
	DNSQuestion *const q = tcpInfo->question;
	tcpInfo_t **backpointer =
		q                 ? &q           ->tcp :
		tcpInfo->rr       ? &tcpInfo->rr ->tcp : mDNSNULL;
	if (backpointer && *backpointer != tcpInfo)
		LogMsg("tcpCallback: %d backpointer %p incorrect tcpInfo %p question %p rr %p",
			mDNSPlatformTCPGetFD(tcpInfo->sock), *backpointer, tcpInfo, q, tcpInfo->rr);

	if (err) goto exit;

	if (ConnectionEstablished)
		{
		mDNSu8    *end = ((mDNSu8*) &tcpInfo->request) + tcpInfo->requestLen;
		DomainAuthInfo *AuthInfo;

		// Defensive coding for <rdar://problem/5546824> Crash in mDNSResponder at GetAuthInfoForName_internal + 366
		// Don't know yet what's causing this, but at least we can be cautious and try to avoid crashing if we find our pointers in an unexpected state
		if (tcpInfo->rr && tcpInfo->rr->resrec.name != &tcpInfo->rr->namestorage)
			LogMsg("tcpCallback: ERROR: tcpInfo->rr->resrec.name %p != &tcpInfo->rr->namestorage %p",
				tcpInfo->rr->resrec.name, &tcpInfo->rr->namestorage);
		if (tcpInfo->rr  && tcpInfo->rr->        resrec.name != &tcpInfo->rr->        namestorage) return;

		AuthInfo =  tcpInfo->rr  ? GetAuthInfoForName(m, tcpInfo->rr->resrec.name)         : mDNSNULL;

		// connection is established - send the message
		if (q && q->LongLived && q->state == LLQ_Established)
			{
			// Lease renewal over TCP, resulting from opening a TCP connection in sendLLQRefresh
			end = ((mDNSu8*) &tcpInfo->request) + tcpInfo->requestLen;
			}
		else if (q && q->LongLived && q->state != LLQ_Poll && !mDNSIPPortIsZero(m->LLQNAT.ExternalPort) && !mDNSIPPortIsZero(q->servPort))
			{
			// Notes:
			// If we have a NAT port mapping, ExternalPort is the external port
			// If we have a routable address so we don't need a port mapping, ExternalPort is the same as our own internal port
			// If we need a NAT port mapping but can't get one, then ExternalPort is zero
			LLQOptData llqData;			// set llq rdata
			llqData.vers  = kLLQ_Vers;
			llqData.llqOp = kLLQOp_Setup;
			llqData.err   = GetLLQEventPort(m, &tcpInfo->Addr);	// We're using TCP; tell server what UDP port to send notifications to
			LogInfo("tcpCallback: eventPort %d", llqData.err);
			llqData.id    = zeroOpaque64;
			llqData.llqlease = kLLQ_DefLease;
			InitializeDNSMessage(&tcpInfo->request.h, q->TargetQID, uQueryFlags);
			end = putLLQ(&tcpInfo->request, tcpInfo->request.data, q, &llqData);
			if (!end) { LogMsg("ERROR: tcpCallback - putLLQ"); err = mStatus_UnknownErr; goto exit; }
			AuthInfo = q->AuthInfo;		// Need to add TSIG to this message
			q->ntries = 0; // Reset ntries so that tcp/tls connection failures don't affect sendChallengeResponse failures
			}
		else if (q)
			{
			// LLQ Polling mode or non-LLQ uDNS over TCP
			InitializeDNSMessage(&tcpInfo->request.h, q->TargetQID, uQueryFlags);
			end = putQuestion(&tcpInfo->request, tcpInfo->request.data, tcpInfo->request.data + AbsoluteMaxDNSMessageData, &q->qname, q->qtype, q->qclass);
			AuthInfo = q->AuthInfo;		// Need to add TSIG to this message
			}

		err = mDNSSendDNSMessage(m, &tcpInfo->request, end, mDNSInterface_Any, mDNSNULL, &tcpInfo->Addr, tcpInfo->Port, sock, AuthInfo);
		if (err) { debugf("ERROR: tcpCallback: mDNSSendDNSMessage - %d", err); err = mStatus_UnknownErr; goto exit; }

		// Record time we sent this question
		if (q)
			{
			mDNS_Lock(m);
			q->LastQTime = m->timenow;
			if (q->ThisQInterval < (256 * mDNSPlatformOneSecond))	// Now we have a TCP connection open, make sure we wait at least 256 seconds before retrying
				q->ThisQInterval = (256 * mDNSPlatformOneSecond);
			SetNextQueryTime(m, q);
			mDNS_Unlock(m);
			}
		}
	else
		{
		long n;
		if (tcpInfo->nread < 2)			// First read the two-byte length preceeding the DNS message
			{
			mDNSu8 *lenptr = (mDNSu8 *)&tcpInfo->replylen;
			n = mDNSPlatformReadTCP(sock, lenptr + tcpInfo->nread, 2 - tcpInfo->nread, &closed);
			if (n < 0)
				{
				LogMsg("ERROR: tcpCallback - attempt to read message length failed (%d)", n);
				err = mStatus_ConnFailed;
				goto exit;
				}
			else if (closed)
				{
				// It's perfectly fine for this socket to close after the first reply. The server might
				// be sending gratuitous replies using UDP and doesn't have a need to leave the TCP socket open.
				// We'll only log this event if we've never received a reply before.
				// BIND 9 appears to close an idle connection after 30 seconds.
				if (tcpInfo->numReplies == 0)
					{
					LogMsg("ERROR: socket closed prematurely tcpInfo->nread = %d", tcpInfo->nread);
					err = mStatus_ConnFailed;
					goto exit;
					}
				else
					{
					// Note that we may not be doing the best thing if an error occurs after we've sent a second request
					// over this tcp connection.  That is, we only track whether we've received at least one response
					// which may have been to a previous request sent over this tcp connection.
					if (backpointer) *backpointer = mDNSNULL; // Clear client backpointer FIRST so we don't risk double-disposing our tcpInfo_t 
					DisposeTCPConn(tcpInfo);
					return;
					}
				}

			tcpInfo->nread += n;
			if (tcpInfo->nread < 2) goto exit;

			tcpInfo->replylen = (mDNSu16)((mDNSu16)lenptr[0] << 8 | lenptr[1]);
			if (tcpInfo->replylen < sizeof(DNSMessageHeader))
				{ LogMsg("ERROR: tcpCallback - length too short (%d bytes)", tcpInfo->replylen); err = mStatus_UnknownErr; goto exit; }

			tcpInfo->reply = mDNSPlatformMemAllocate(tcpInfo->replylen);
			if (!tcpInfo->reply) { LogMsg("ERROR: tcpCallback - malloc failed"); err = mStatus_NoMemoryErr; goto exit; }
			}

		n = mDNSPlatformReadTCP(sock, ((char *)tcpInfo->reply) + (tcpInfo->nread - 2), tcpInfo->replylen - (tcpInfo->nread - 2), &closed);

		if (n < 0)
			{
			LogMsg("ERROR: tcpCallback - read returned %d", n);
			err = mStatus_ConnFailed;
			goto exit;
			}
		else if (closed)
			{
			if (tcpInfo->numReplies == 0)
				{
				LogMsg("ERROR: socket closed prematurely tcpInfo->nread = %d", tcpInfo->nread);
				err = mStatus_ConnFailed;
				goto exit;
				}
			else
				{
				// Note that we may not be doing the best thing if an error occurs after we've sent a second request
				// over this tcp connection.  That is, we only track whether we've received at least one response
				// which may have been to a previous request sent over this tcp connection.
				if (backpointer) *backpointer = mDNSNULL; // Clear client backpointer FIRST so we don't risk double-disposing our tcpInfo_t 
				DisposeTCPConn(tcpInfo);
				return;
				}
			}

		tcpInfo->nread += n;

		if ((tcpInfo->nread - 2) == tcpInfo->replylen)
			{
			mDNSBool tls;
			DNSMessage *reply = tcpInfo->reply;
			mDNSu8     *end   = (mDNSu8 *)tcpInfo->reply + tcpInfo->replylen;
			mDNSAddr    Addr  = tcpInfo->Addr;
			mDNSIPPort  Port  = tcpInfo->Port;
			mDNSIPPort srcPort = zeroIPPort;
			tcpInfo->numReplies++;
			tcpInfo->reply    = mDNSNULL;	// Detach reply buffer from tcpInfo_t, to make sure client callback can't cause it to be disposed
			tcpInfo->nread    = 0;
			tcpInfo->replylen = 0;
			
			// If we're going to dispose this connection, do it FIRST, before calling client callback
			// Note: Sleep code depends on us clearing *backpointer here -- it uses the clearing of rr->tcp
			// as the signal that the DNS deregistration operation with the server has completed, and the machine may now sleep
			// If we clear the tcp pointer in the question, mDNSCoreReceiveResponse cannot find a matching question. Hence
			// we store the minimal information i.e., the source port of the connection in the question itself.
			// Dereference sock before it is disposed in DisposeTCPConn below.
			
			if (sock->flags & kTCPSocketFlags_UseTLS) tls = mDNStrue;
			else tls = mDNSfalse;

			if (q && q->tcp) {srcPort = q->tcp->SrcPort; q->tcpSrcPort = srcPort;}
			
			if (backpointer)
				if (!q || !q->LongLived || m->SleepState)
					{ *backpointer = mDNSNULL; DisposeTCPConn(tcpInfo); }
			
			mDNSCoreReceive(m, reply, end, &Addr, Port, tls ? (mDNSAddr *)1 : mDNSNULL, srcPort, 0);
			// USE CAUTION HERE: Invoking mDNSCoreReceive may have caused the environment to change, including canceling this operation itself
			
			mDNSPlatformMemFree(reply);
			return;
			}
		}

exit:

	if (err)
		{
		// Clear client backpointer FIRST -- that way if one of the callbacks cancels its operation
		// we won't end up double-disposing our tcpInfo_t
		if (backpointer) *backpointer = mDNSNULL;

		mDNS_Lock(m);		// Need to grab the lock to get m->timenow

		if (q)
			{
			if (q->ThisQInterval == 0)
				{
				// We get here when we fail to establish a new TCP/TLS connection that would have been used for a new LLQ request or an LLQ renewal.
				// Note that ThisQInterval is also zero when sendChallengeResponse resends the LLQ request on an extant TCP/TLS connection.
				q->LastQTime = m->timenow;
				if (q->LongLived)
					{
					// We didn't get the chance to send our request packet before the TCP/TLS connection failed.
					// We want to retry quickly, but want to back off exponentially in case the server is having issues.
					// Since ThisQInterval was 0, we can't just multiply by QuestionIntervalStep, we must track the number
					// of TCP/TLS connection failures using ntries.
					mDNSu32 count = q->ntries + 1; // want to wait at least 1 second before retrying

					q->ThisQInterval = InitialQuestionInterval;

					for (;count;count--)
						q->ThisQInterval *= QuestionIntervalStep;

					if (q->ThisQInterval > LLQ_POLL_INTERVAL)
						q->ThisQInterval = LLQ_POLL_INTERVAL;
					else
						q->ntries++;
						
					LogMsg("tcpCallback: stream connection for LLQ %##s (%s) failed %d times, retrying in %d ms", q->qname.c, DNSTypeName(q->qtype), q->ntries, q->ThisQInterval);
					}
				else
					{
					q->ThisQInterval = MAX_UCAST_POLL_INTERVAL;
					LogMsg("tcpCallback: stream connection for %##s (%s) failed, retrying in %d ms", q->qname.c, DNSTypeName(q->qtype), q->ThisQInterval);
					}
				SetNextQueryTime(m, q);
				}
			else if (NextQSendTime(q) - m->timenow > (q->LongLived ? LLQ_POLL_INTERVAL : MAX_UCAST_POLL_INTERVAL))
				{
				// If we get an error and our next scheduled query for this question is more than the max interval from now,
				// reset the next query to ensure we wait no longer the maximum interval from now before trying again.
				q->LastQTime     = m->timenow;
				q->ThisQInterval = q->LongLived ? LLQ_POLL_INTERVAL : MAX_UCAST_POLL_INTERVAL;
				SetNextQueryTime(m, q);
				LogMsg("tcpCallback: stream connection for %##s (%s) failed, retrying in %d ms", q->qname.c, DNSTypeName(q->qtype), q->ThisQInterval);
				}
			
			// We're about to dispose of the TCP connection, so we must reset the state to retry over TCP/TLS
			// because sendChallengeResponse will send the query via UDP if we don't have a tcp pointer.
			// Resetting to LLQ_InitialRequest will cause uDNS_CheckCurrentQuestion to call startLLQHandshake, which
			// will attempt to establish a new tcp connection.
			if (q->LongLived && q->state == LLQ_SecondaryRequest)
				q->state = LLQ_InitialRequest;
			
			// ConnFailed may happen if the server sends a TCP reset or TLS fails, in which case we want to retry establishing the LLQ
			// quickly rather than switching to polling mode.  This case is handled by the above code to set q->ThisQInterval just above.
			// If the error isn't ConnFailed, then the LLQ is in bad shape, so we switch to polling mode.
			if (err != mStatus_ConnFailed)
				{
				if (q->LongLived && q->state != LLQ_Poll) StartLLQPolling(m, q);
				}
			}

		mDNS_Unlock(m);

		DisposeTCPConn(tcpInfo);
		}
	}

mDNSlocal tcpInfo_t *MakeTCPConn(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end,
	TCPSocketFlags flags, const mDNSAddr *const Addr, const mDNSIPPort Port, domainname *hostname,
	DNSQuestion *const question, AuthRecord *const rr)
	{
	mStatus err;
	mDNSIPPort srcport = zeroIPPort;
	tcpInfo_t *info;

	if ((flags & kTCPSocketFlags_UseTLS) && (!hostname || !hostname->c[0]))
		{ LogMsg("MakeTCPConn: TLS connection being setup with NULL hostname"); return mDNSNULL; }

	info = (tcpInfo_t *)mDNSPlatformMemAllocate(sizeof(tcpInfo_t));
	if (!info) { LogMsg("ERROR: MakeTCP - memallocate failed"); return(mDNSNULL); }
	mDNSPlatformMemZero(info, sizeof(tcpInfo_t));

	info->m          = m;
	info->sock       = mDNSPlatformTCPSocket(m, flags, &srcport);
	info->requestLen = 0;
	info->question   = question;
	info->rr         = rr;
	info->Addr       = *Addr;
	info->Port       = Port;
	info->reply      = mDNSNULL;
	info->replylen   = 0;
	info->nread      = 0;
	info->numReplies = 0;
	info->SrcPort = srcport;

	if (msg)
		{
		info->requestLen = (int) (end - ((mDNSu8*)msg));
		mDNSPlatformMemCopy(&info->request, msg, info->requestLen);
		}

	if (!info->sock) { LogMsg("MakeTCPConn: unable to create TCP socket"); mDNSPlatformMemFree(info); return(mDNSNULL); }
	err = mDNSPlatformTCPConnect(info->sock, Addr, Port, hostname, (question ? question->InterfaceID : mDNSNULL), tcpCallback, info);

	// Probably suboptimal here.
	// Instead of returning mDNSNULL here on failure, we should probably invoke the callback with an error code.
	// That way clients can put all the error handling and retry/recovery code in one place,
	// instead of having to handle immediate errors in one place and async errors in another.
	// Also: "err == mStatus_ConnEstablished" probably never happens.

	// Don't need to log "connection failed" in customer builds -- it happens quite often during sleep, wake, configuration changes, etc.
	if      (err == mStatus_ConnEstablished) { tcpCallback(info->sock, info, mDNStrue, mStatus_NoError); }
	else if (err != mStatus_ConnPending    ) { LogInfo("MakeTCPConn: connection failed"); DisposeTCPConn(info); return(mDNSNULL); }
	return(info);
	}

mDNSexport void DisposeTCPConn(struct tcpInfo_t *tcp)
	{
	mDNSPlatformTCPCloseConnection(tcp->sock);
	if (tcp->reply) mDNSPlatformMemFree(tcp->reply);
	mDNSPlatformMemFree(tcp);
	}

// Lock must be held
mDNSexport void startLLQHandshake(mDNS *m, DNSQuestion *q)
	{
	if (mDNSIPv4AddressIsOnes(m->LLQNAT.ExternalAddress))
		{
		LogInfo("startLLQHandshake: waiting for NAT status for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
		q->ThisQInterval = LLQ_POLL_INTERVAL + mDNSRandom(LLQ_POLL_INTERVAL/10);	// Retry in approx 15 minutes
		q->LastQTime = m->timenow;
		SetNextQueryTime(m, q);
		return;
		}

	// Either we don't have NAT-PMP support (ExternalPort is zero) or behind a Double NAT that may or
	// may not have NAT-PMP support (NATResult is non-zero)
	if (mDNSIPPortIsZero(m->LLQNAT.ExternalPort) || m->LLQNAT.Result)
		{
		LogInfo("startLLQHandshake: Cannot receive inbound packets; will poll for %##s (%s) External Port %d, NAT Result %d",
			q->qname.c, DNSTypeName(q->qtype), mDNSVal16(m->LLQNAT.ExternalPort), m->LLQNAT.Result);
		StartLLQPolling(m, q);
		return;
		}

	if (mDNSIPPortIsZero(q->servPort))
		{
		debugf("startLLQHandshake: StartGetZoneData for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
		q->ThisQInterval = LLQ_POLL_INTERVAL + mDNSRandom(LLQ_POLL_INTERVAL/10);	// Retry in approx 15 minutes
		q->LastQTime     = m->timenow;
		SetNextQueryTime(m, q);
		q->servAddr = zeroAddr;
		// We know q->servPort is zero because of check above
		if (q->nta) CancelGetZoneData(m, q->nta);
		q->nta = StartGetZoneData(m, &q->qname, ZoneServiceLLQ, LLQGotZoneData, q);
		return;
		}

	if (PrivateQuery(q))
		{
		if (q->tcp) LogInfo("startLLQHandshake: Disposing existing TCP connection for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
		if (q->tcp) { DisposeTCPConn(q->tcp); q->tcp = mDNSNULL; }
		if (!q->nta)
			{
			// Normally we lookup the zone data and then call this function. And we never free the zone data
			// for "PrivateQuery". But sometimes this can happen due to some race conditions. When we
			// switch networks, we might end up "Polling" the network e.g., we are behind a Double NAT.
			// When we poll, we free the zone information as we send the query to the server (See
			// PrivateQueryGotZoneData). The NAT callback (LLQNATCallback) may happen soon after that. If we
			// are still behind Double NAT, we would have returned early in this function. But we could
			// have switched to a network with no NATs and we should get the zone data again.
			LogInfo("startLLQHandshake: nta is NULL for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
			q->nta = StartGetZoneData(m, &q->qname, ZoneServiceLLQ, LLQGotZoneData, q);
			return;
			}
		else if (!q->nta->Host.c[0])
			{
			// This should not happen. If it happens, we print a log and MakeTCPConn will fail if it can't find a hostname
			LogMsg("startLLQHandshake: ERROR!!: nta non NULL for %##s (%s) but HostName %d NULL, LongLived %d", q->qname.c, DNSTypeName(q->qtype), q->nta->Host.c[0], q->LongLived);
			}
		q->tcp = MakeTCPConn(m, mDNSNULL, mDNSNULL, kTCPSocketFlags_UseTLS, &q->servAddr, q->servPort, &q->nta->Host, q, mDNSNULL);
		if (!q->tcp)
			q->ThisQInterval = mDNSPlatformOneSecond * 5;	// If TCP failed (transient networking glitch) try again in five seconds
		else
			{
			q->state         = LLQ_SecondaryRequest;		// Right now, for private DNS, we skip the four-way LLQ handshake
			q->ReqLease      = kLLQ_DefLease;
			q->ThisQInterval = 0;
			}
		q->LastQTime     = m->timenow;
		SetNextQueryTime(m, q);
		}
	else
		{
		debugf("startLLQHandshake: m->AdvertisedV4 %#a%s Server %#a:%d%s %##s (%s)",
			&m->AdvertisedV4,                     mDNSv4AddrIsRFC1918(&m->AdvertisedV4.ip.v4) ? " (RFC 1918)" : "",
			&q->servAddr, mDNSVal16(q->servPort), mDNSAddrIsRFC1918(&q->servAddr)             ? " (RFC 1918)" : "",
			q->qname.c, DNSTypeName(q->qtype));

		if (q->ntries++ >= kLLQ_MAX_TRIES)
			{
			LogMsg("startLLQHandshake: %d failed attempts for LLQ %##s Polling.", kLLQ_MAX_TRIES, q->qname.c);
			StartLLQPolling(m, q);
			}
		else
			{
			mDNSu8 *end;
			LLQOptData llqData;

			// set llq rdata
			llqData.vers  = kLLQ_Vers;
			llqData.llqOp = kLLQOp_Setup;
			llqData.err   = LLQErr_NoError;	// Don't need to tell server UDP notification port when sending over UDP
			llqData.id    = zeroOpaque64;
			llqData.llqlease = kLLQ_DefLease;
	
			InitializeDNSMessage(&m->omsg.h, q->TargetQID, uQueryFlags);
			end = putLLQ(&m->omsg, m->omsg.data, q, &llqData);
			if (!end) { LogMsg("ERROR: startLLQHandshake - putLLQ"); StartLLQPolling(m,q); return; }
	
			mDNSSendDNSMessage(m, &m->omsg, end, mDNSInterface_Any, q->LocalSocket, &q->servAddr, q->servPort, mDNSNULL, mDNSNULL);
	
			// update question state
			q->state         = LLQ_InitialRequest;
			q->ReqLease      = kLLQ_DefLease;
			q->ThisQInterval = (kLLQ_INIT_RESEND * mDNSPlatformOneSecond);
			q->LastQTime     = m->timenow;
			SetNextQueryTime(m, q);
			}
		}
	}

// forward declaration so GetServiceTarget can do reverse lookup if needed
mDNSlocal void GetStaticHostname(mDNS *m);

mDNSexport const domainname *GetServiceTarget(mDNS *m, AuthRecord *const rr)
	{
	debugf("GetServiceTarget %##s", rr->resrec.name->c);

	if (!rr->AutoTarget)		// If not automatically tracking this host's current name, just return the existing target
		return(&rr->resrec.rdata->u.srv.target);
	else
		{
#if APPLE_OSX_mDNSResponder
		DomainAuthInfo *AuthInfo = GetAuthInfoForName_internal(m, rr->resrec.name);
		if (AuthInfo && AuthInfo->AutoTunnel)
			{
			// If this AutoTunnel is not yet active, start it now (which entails activating its NAT Traversal request,
			// which will subsequently advertise the appropriate records when the NAT Traversal returns a result)
			if (!AuthInfo->AutoTunnelNAT.clientContext && m->AutoTunnelHostAddr.b[0])
				{
				LogInfo("GetServiceTarget: Calling SetupLocalAutoTunnelInterface_internal");
				SetupLocalAutoTunnelInterface_internal(m, mDNStrue);
				}
			if (AuthInfo->AutoTunnelHostRecord.namestorage.c[0] == 0) return(mDNSNULL);
			debugf("GetServiceTarget: Returning %##s", AuthInfo->AutoTunnelHostRecord.namestorage.c);
			return(&AuthInfo->AutoTunnelHostRecord.namestorage);
			}
		else
#endif // APPLE_OSX_mDNSResponder
			{
			const int srvcount = CountLabels(rr->resrec.name);
			HostnameInfo *besthi = mDNSNULL, *hi;
			int best = 0;
			for (hi = m->Hostnames; hi; hi = hi->next)
				if (hi->arv4.state == regState_Registered || hi->arv4.state == regState_Refresh ||
					hi->arv6.state == regState_Registered || hi->arv6.state == regState_Refresh)
					{
					int x, hostcount = CountLabels(&hi->fqdn);
					for (x = hostcount < srvcount ? hostcount : srvcount; x > 0 && x > best; x--)
						if (SameDomainName(SkipLeadingLabels(rr->resrec.name, srvcount - x), SkipLeadingLabels(&hi->fqdn, hostcount - x)))
							{ best = x; besthi = hi; }
					}
	
			if (besthi) return(&besthi->fqdn);
			}
		if (m->StaticHostname.c[0]) return(&m->StaticHostname);
		else GetStaticHostname(m); // asynchronously do reverse lookup for primary IPv4 address
		LogInfo("GetServiceTarget: Returning NULL for %s", ARDisplayString(m, rr));
		return(mDNSNULL);
		}
	}

mDNSlocal const domainname *PUBLIC_UPDATE_SERVICE_TYPE  = (const domainname*)"\x0B_dns-update"     "\x04_udp";
mDNSlocal const domainname *PUBLIC_LLQ_SERVICE_TYPE     = (const domainname*)"\x08_dns-llq"        "\x04_udp";

mDNSlocal const domainname *PRIVATE_UPDATE_SERVICE_TYPE = (const domainname*)"\x0F_dns-update-tls" "\x04_tcp";
mDNSlocal const domainname *PRIVATE_QUERY_SERVICE_TYPE  = (const domainname*)"\x0E_dns-query-tls"  "\x04_tcp";
mDNSlocal const domainname *PRIVATE_LLQ_SERVICE_TYPE    = (const domainname*)"\x0C_dns-llq-tls"    "\x04_tcp";

#define ZoneDataSRV(X) (\
	(X)->ZoneService == ZoneServiceUpdate ? ((X)->ZonePrivate ? PRIVATE_UPDATE_SERVICE_TYPE : PUBLIC_UPDATE_SERVICE_TYPE) : \
	(X)->ZoneService == ZoneServiceQuery  ? ((X)->ZonePrivate ? PRIVATE_QUERY_SERVICE_TYPE  : (const domainname*)""     ) : \
	(X)->ZoneService == ZoneServiceLLQ    ? ((X)->ZonePrivate ? PRIVATE_LLQ_SERVICE_TYPE    : PUBLIC_LLQ_SERVICE_TYPE   ) : (const domainname*)"")

// Forward reference: GetZoneData_StartQuery references GetZoneData_QuestionCallback, and
// GetZoneData_QuestionCallback calls GetZoneData_StartQuery
mDNSlocal mStatus GetZoneData_StartQuery(mDNS *const m, ZoneData *zd, mDNSu16 qtype);

// GetZoneData_QuestionCallback is called from normal client callback context (core API calls allowed)
mDNSlocal void GetZoneData_QuestionCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
	{
	ZoneData *zd = (ZoneData*)question->QuestionContext;

	debugf("GetZoneData_QuestionCallback: %s %s", AddRecord ? "Add" : "Rmv", RRDisplayString(m, answer));

	if (!AddRecord) return;												// Don't care about REMOVE events
	if (AddRecord == QC_addnocache && answer->rdlength == 0) return;	// Don't care about transient failure indications
	if (answer->rrtype != question->qtype) return;						// Don't care about CNAMEs

	if (answer->rrtype == kDNSType_SOA)
		{
		debugf("GetZoneData GOT SOA %s", RRDisplayString(m, answer));
		mDNS_StopQuery(m, question);
		if (question->ThisQInterval != -1)
			LogMsg("GetZoneData_QuestionCallback: Question %##s (%s) ThisQInterval %d not -1", question->qname.c, DNSTypeName(question->qtype), question->ThisQInterval);
		if (answer->rdlength)
			{
			AssignDomainName(&zd->ZoneName, answer->name);
			zd->ZoneClass = answer->rrclass;
			AssignDomainName(&zd->question.qname, &zd->ZoneName);
			GetZoneData_StartQuery(m, zd, kDNSType_SRV);
			}
		else if (zd->CurrentSOA->c[0])
			{
			DomainAuthInfo *AuthInfo = GetAuthInfoForName(m, zd->CurrentSOA);
			if (AuthInfo && AuthInfo->AutoTunnel)
				{
				// To keep the load on the server down, we don't chop down on
				// SOA lookups for AutoTunnels
				LogInfo("GetZoneData_QuestionCallback: not chopping labels for %##s", zd->CurrentSOA->c);
				zd->ZoneDataCallback(m, mStatus_NoSuchNameErr, zd);
				}
			else 
				{
				zd->CurrentSOA = (domainname *)(zd->CurrentSOA->c + zd->CurrentSOA->c[0]+1);
				AssignDomainName(&zd->question.qname, zd->CurrentSOA);
				GetZoneData_StartQuery(m, zd, kDNSType_SOA);
				}
			}
		else
			{
			LogInfo("GetZoneData recursed to root label of %##s without finding SOA", zd->ChildName.c);
			zd->ZoneDataCallback(m, mStatus_NoSuchNameErr, zd);
			}
		}
	else if (answer->rrtype == kDNSType_SRV)
		{
		debugf("GetZoneData GOT SRV %s", RRDisplayString(m, answer));
		mDNS_StopQuery(m, question);
		if (question->ThisQInterval != -1)
			LogMsg("GetZoneData_QuestionCallback: Question %##s (%s) ThisQInterval %d not -1", question->qname.c, DNSTypeName(question->qtype), question->ThisQInterval);
// Right now we don't want to fail back to non-encrypted operations
// If the AuthInfo has the AutoTunnel field set, then we want private or nothing
// <rdar://problem/5687667> BTMM: Don't fallback to unencrypted operations when SRV lookup fails
#if 0
		if (!answer->rdlength && zd->ZonePrivate && zd->ZoneService != ZoneServiceQuery)
			{
			zd->ZonePrivate = mDNSfalse;	// Causes ZoneDataSRV() to yield a different SRV name when building the query
			GetZoneData_StartQuery(m, zd, kDNSType_SRV);		// Try again, non-private this time
			}
		else
#endif
			{
			if (answer->rdlength)
				{
				AssignDomainName(&zd->Host, &answer->rdata->u.srv.target);
				zd->Port = answer->rdata->u.srv.port;
				AssignDomainName(&zd->question.qname, &zd->Host);
				GetZoneData_StartQuery(m, zd, kDNSType_A);
				}
			else
				{
				zd->ZonePrivate = mDNSfalse;
				zd->Host.c[0] = 0;
				zd->Port = zeroIPPort;
				zd->Addr = zeroAddr;
				zd->ZoneDataCallback(m, mStatus_NoError, zd);
				}
			}
		}
	else if (answer->rrtype == kDNSType_A)
		{
		debugf("GetZoneData GOT A %s", RRDisplayString(m, answer));
		mDNS_StopQuery(m, question);
		if (question->ThisQInterval != -1)
			LogMsg("GetZoneData_QuestionCallback: Question %##s (%s) ThisQInterval %d not -1", question->qname.c, DNSTypeName(question->qtype), question->ThisQInterval);
		zd->Addr.type  = mDNSAddrType_IPv4;
		zd->Addr.ip.v4 = (answer->rdlength == 4) ? answer->rdata->u.ipv4 : zerov4Addr;
		// In order to simulate firewalls blocking our outgoing TCP connections, returning immediate ICMP errors or TCP resets,
		// the code below will make us try to connect to loopback, resulting in an immediate "port unreachable" failure.
		// This helps us test to make sure we handle this case gracefully
		// <rdar://problem/5607082> BTMM: mDNSResponder taking 100 percent CPU after upgrading to 10.5.1
#if 0
		zd->Addr.ip.v4.b[0] = 127;
		zd->Addr.ip.v4.b[1] = 0;
		zd->Addr.ip.v4.b[2] = 0;
		zd->Addr.ip.v4.b[3] = 1;
#endif
		// The caller needs to free the memory when done with zone data
		zd->ZoneDataCallback(m, mStatus_NoError, zd);
		}
	}

// GetZoneData_StartQuery is called from normal client context (lock not held, or client callback)
mDNSlocal mStatus GetZoneData_StartQuery(mDNS *const m, ZoneData *zd, mDNSu16 qtype)
	{
	if (qtype == kDNSType_SRV)
		{
		AssignDomainName(&zd->question.qname, ZoneDataSRV(zd));
		AppendDomainName(&zd->question.qname, &zd->ZoneName);
		debugf("lookupDNSPort %##s", zd->question.qname.c);
		}

	// CancelGetZoneData can get called at any time. We should stop the question if it has not been
	// stopped already. A value of -1 for ThisQInterval indicates that the question is not active
	// yet.
	zd->question.ThisQInterval       = -1;
	zd->question.InterfaceID         = mDNSInterface_Any;
	zd->question.Target              = zeroAddr;
	//zd->question.qname.c[0]        = 0;			// Already set
	zd->question.qtype               = qtype;
	zd->question.qclass              = kDNSClass_IN;
	zd->question.LongLived           = mDNSfalse;
	zd->question.ExpectUnique        = mDNStrue;
	zd->question.ForceMCast          = mDNSfalse;
	zd->question.ReturnIntermed      = mDNStrue;
	zd->question.SuppressUnusable    = mDNSfalse;
	zd->question.QuestionCallback    = GetZoneData_QuestionCallback;
	zd->question.QuestionContext     = zd;

	//LogMsg("GetZoneData_StartQuery %##s (%s) %p", zd->question.qname.c, DNSTypeName(zd->question.qtype), zd->question.Private);
	return(mDNS_StartQuery(m, &zd->question));
	}

// StartGetZoneData is an internal routine (i.e. must be called with the lock already held)
mDNSexport ZoneData *StartGetZoneData(mDNS *const m, const domainname *const name, const ZoneService target, ZoneDataCallback callback, void *ZoneDataContext)
	{
	DomainAuthInfo *AuthInfo = GetAuthInfoForName_internal(m, name);
	int initialskip = (AuthInfo && AuthInfo->AutoTunnel) ? DomainNameLength(name) - DomainNameLength(&AuthInfo->domain) : 0;
	ZoneData *zd = (ZoneData*)mDNSPlatformMemAllocate(sizeof(ZoneData));
	if (!zd) { LogMsg("ERROR: StartGetZoneData - mDNSPlatformMemAllocate failed"); return mDNSNULL; }
	mDNSPlatformMemZero(zd, sizeof(ZoneData));
	AssignDomainName(&zd->ChildName, name);
	zd->ZoneService      = target;
	zd->CurrentSOA       = (domainname *)(&zd->ChildName.c[initialskip]);
	zd->ZoneName.c[0]    = 0;
	zd->ZoneClass        = 0;
	zd->Host.c[0]        = 0;
	zd->Port             = zeroIPPort;
	zd->Addr             = zeroAddr;
	zd->ZonePrivate      = AuthInfo && AuthInfo->AutoTunnel ? mDNStrue : mDNSfalse;
	zd->ZoneDataCallback = callback;
	zd->ZoneDataContext  = ZoneDataContext;

	zd->question.QuestionContext = zd;
	AssignDomainName(&zd->question.qname, zd->CurrentSOA);

	mDNS_DropLockBeforeCallback();		// GetZoneData_StartQuery expects to be called from a normal callback, so we emulate that here
	GetZoneData_StartQuery(m, zd, kDNSType_SOA);
	mDNS_ReclaimLockAfterCallback();

	return zd;
	}

// GetZoneData queries are a special case -- even if we have a key for them, we don't do them privately,
// because that would result in an infinite loop (i.e. to do a private query we first need to get
// the _dns-query-tls SRV record for the zone, and we can't do *that* privately because to do so
// we'd need to already know the _dns-query-tls SRV record.
// Also, as a general rule, we never do SOA queries privately
mDNSexport DomainAuthInfo *GetAuthInfoForQuestion(mDNS *m, const DNSQuestion *const q)	// Must be called with lock held
	{
	if (q->QuestionCallback == GetZoneData_QuestionCallback) return(mDNSNULL);
	if (q->qtype            == kDNSType_SOA                ) return(mDNSNULL);
	return(GetAuthInfoForName_internal(m, &q->qname));
	}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - host name and interface management
#endif

mDNSlocal void SendRecordRegistration(mDNS *const m, AuthRecord *rr);
mDNSlocal void SendRecordDeregistration(mDNS *m, AuthRecord *rr);
mDNSlocal mDNSBool IsRecordMergeable(mDNS *const m, AuthRecord *rr, mDNSs32 time);

// When this function is called, service record is already deregistered. We just
// have to deregister the PTR and TXT records.
mDNSlocal void UpdateAllServiceRecords(mDNS *const m, AuthRecord *rr, mDNSBool reg)
	{
	AuthRecord *r, *srvRR;

	if (rr->resrec.rrtype != kDNSType_SRV) { LogMsg("UpdateAllServiceRecords:ERROR!! ResourceRecord not a service record %s", ARDisplayString(m, rr)); return; }

	if (reg && rr->state == regState_NoTarget) { LogMsg("UpdateAllServiceRecords:ERROR!! SRV record %s in noTarget state during registration", ARDisplayString(m, rr)); return; }

	LogInfo("UpdateAllServiceRecords: ResourceRecord %s", ARDisplayString(m, rr));

	for (r = m->ResourceRecords; r; r=r->next)
		{
		if (!AuthRecord_uDNS(r)) continue;
		srvRR = mDNSNULL;
		if (r->resrec.rrtype == kDNSType_PTR)
			srvRR = r->Additional1;
		else if (r->resrec.rrtype == kDNSType_TXT)
			srvRR = r->DependentOn;
		if (srvRR && srvRR->resrec.rrtype != kDNSType_SRV)
			LogMsg("UpdateAllServiceRecords: ERROR!! Resource record %s wrong, expecting SRV type", ARDisplayString(m, srvRR));
		if (srvRR == rr)
			{
			if (!reg)
				{
				LogInfo("UpdateAllServiceRecords: deregistering %s", ARDisplayString(m, r));
				r->SRVChanged = mDNStrue;
				r->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
				r->LastAPTime = m->timenow - INIT_RECORD_REG_INTERVAL;
				r->state = regState_DeregPending;
				}
			else 
				{
				// Clearing SRVchanged is a safety measure. If our pewvious dereg never
				// came back and we had a target change, we are starting fresh
				r->SRVChanged = mDNSfalse;
				// if it is already registered or in the process of registering, then don't
				// bother re-registering. This happens today for non-BTMM domains where the
				// TXT and PTR get registered before SRV records because of the delay in
				// getting the port mapping. There is no point in re-registering the TXT
				// and PTR records. 
				if ((r->state == regState_Registered) ||
				    (r->state == regState_Pending && r->nta && !mDNSIPv4AddressIsZero(r->nta->Addr.ip.v4)))
					LogInfo("UpdateAllServiceRecords: not registering %s, state %d", ARDisplayString(m, r), r->state);
				else
					{
					LogInfo("UpdateAllServiceRecords: registering %s, state %d", ARDisplayString(m, r), r->state);
					ActivateUnicastRegistration(m, r);
					}
				}
			}
		}
	}

// Called in normal client context (lock not held)
// Currently only supports SRV records for nat mapping
mDNSlocal void CompleteRecordNatMap(mDNS *m, NATTraversalInfo *n)
	{
	const domainname *target;
	domainname *srvt;
	AuthRecord *rr = (AuthRecord *)n->clientContext;
	debugf("SRVNatMap complete %.4a IntPort %u ExternalPort %u NATLease %u", &n->ExternalAddress, mDNSVal16(n->IntPort), mDNSVal16(n->ExternalPort), n->NATLease);

	if (!rr) { LogMsg("CompleteRecordNatMap called with unknown AuthRecord object"); return; }
	if (!n->NATLease) { LogMsg("CompleteRecordNatMap No NATLease for %s", ARDisplayString(m, rr)); return; }

	if (rr->resrec.rrtype != kDNSType_SRV) {LogMsg("CompleteRecordNatMap: Not a service record %s", ARDisplayString(m, rr)); return; }

	if (rr->resrec.RecordType == kDNSRecordTypeDeregistering) { LogInfo("CompleteRecordNatMap called for %s, Service deregistering", ARDisplayString(m, rr)); return; }

	if (rr->state == regState_DeregPending) { LogInfo("CompleteRecordNatMap called for %s, record in DeregPending", ARDisplayString(m, rr)); return; }

	// As we free the zone info after registering/deregistering with the server (See hndlRecordUpdateReply),
	// we need to restart the get zone data and nat mapping request to get the latest mapping result as we can't handle it
	// at this moment. Restart from the beginning.
	if (!rr->nta || mDNSIPv4AddressIsZero(rr->nta->Addr.ip.v4))
		{
		LogInfo("CompleteRecordNatMap called for %s but no zone information!", ARDisplayString(m, rr));
		// We need to clear out the NATinfo state so that it will result in re-acuqiring the mapping
		// and hence this callback called again.
		if (rr->NATinfo.clientContext)
			{
			mDNS_StopNATOperation_internal(m, &rr->NATinfo);
			rr->NATinfo.clientContext = mDNSNULL;
			}
		rr->state = regState_Pending;
		rr->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
		rr->LastAPTime = m->timenow - INIT_RECORD_REG_INTERVAL;
		return;
		}

	mDNS_Lock(m);
	// Reevaluate the target always as Target could have changed while
	// we were getting the port mapping (See UpdateOneSRVRecord)
	target = GetServiceTarget(m, rr);
	srvt = GetRRDomainNameTarget(&rr->resrec);
	if (!target || target->c[0] == 0 || mDNSIPPortIsZero(n->ExternalPort))
		{
		if (target && target->c[0])
			LogInfo("CompleteRecordNatMap - Target %##s for ResourceRecord %##s, ExternalPort %d", target->c, rr->resrec.name->c, mDNSVal16(n->ExternalPort));
		else
			LogInfo("CompleteRecordNatMap - no target for %##s, ExternalPort %d", rr->resrec.name->c, mDNSVal16(n->ExternalPort));
		if (srvt) srvt->c[0] = 0;
		rr->state = regState_NoTarget;
		rr->resrec.rdlength = rr->resrec.rdestimate = 0;
		mDNS_Unlock(m);
		UpdateAllServiceRecords(m, rr, mDNSfalse);
		return;
		}
	LogInfo("CompleteRecordNatMap - Target %##s for ResourceRecord %##s, ExternalPort %d", target->c, rr->resrec.name->c, mDNSVal16(n->ExternalPort));
	// This function might get called multiple times during a network transition event. Previosuly, we could
	// have put the SRV record in NoTarget state above and deregistered all the other records. When this
	// function gets called again with a non-zero ExternalPort, we need to set the target and register the
	// other records again.
	if (srvt && !SameDomainName(srvt, target))
		{
		AssignDomainName(srvt, target);
		SetNewRData(&rr->resrec, mDNSNULL, 0);		// Update rdlength, rdestimate, rdatahash
		}

	// SRVChanged is set when when the target of the SRV record changes (See UpdateOneSRVRecord).
	// As a result of the target change, we might register just that SRV Record if it was
	// previously registered and we have a new target OR deregister SRV (and the associated
	// PTR/TXT records) if we don't have a target anymore. When we get a response from the server,
	// SRVChanged state tells that we registered/deregistered because of a target change
	// and hence handle accordingly e.g., if we deregistered, put the records in NoTarget state OR
	// if we registered then put it in Registered state.
	//
	// Here, we are registering all the records again from the beginning. Treat this as first time
	// registration rather than a temporary target change.
	rr->SRVChanged = mDNSfalse;

	// We want IsRecordMergeable to check whether it is a record whose update can be
	// sent with others. We set the time before we call IsRecordMergeable, so that
	// it does not fail this record based on time. We are interested in other checks
	// at this time
	rr->state = regState_Pending;
	rr->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
	rr->LastAPTime = m->timenow - INIT_RECORD_REG_INTERVAL;
	if (IsRecordMergeable(m, rr, m->timenow + MERGE_DELAY_TIME))
		// Delay the record registration by MERGE_DELAY_TIME so that we can merge them
		// into one update
		rr->LastAPTime += MERGE_DELAY_TIME;
	mDNS_Unlock(m);
	// We call this always even though it may not be necessary always e.g., normal registration
	// process where TXT and PTR gets registered followed by the SRV record after it gets
	// the port mapping. In that case, UpdateAllServiceRecords handles the optimization. The
	// update of TXT and PTR record is required if we entered noTargetState before as explained
	// above.
	UpdateAllServiceRecords(m, rr, mDNStrue);
	}

mDNSlocal void StartRecordNatMap(mDNS *m, AuthRecord *rr)
	{
	const mDNSu8 *p;
	mDNSu8 protocol;

	if (rr->resrec.rrtype != kDNSType_SRV)
		{
		LogInfo("StartRecordNatMap: Resource Record %##s type %d, not supported", rr->resrec.name->c, rr->resrec.rrtype);
		return;
		}
	p = rr->resrec.name->c;
	//Assume <Service Instance>.<App Protocol>.<Transport protocol>.<Name>
	// Skip the first two labels to get to the transport protocol
	if (p[0]) p += 1 + p[0];
	if (p[0]) p += 1 + p[0];
	if      (SameDomainLabel(p, (mDNSu8 *)"\x4" "_tcp")) protocol = NATOp_MapTCP;
	else if (SameDomainLabel(p, (mDNSu8 *)"\x4" "_udp")) protocol = NATOp_MapUDP;
	else { LogMsg("StartRecordNatMap: could not determine transport protocol of service %##s", rr->resrec.name->c); return; }
	
	if (rr->NATinfo.clientContext) mDNS_StopNATOperation_internal(m, &rr->NATinfo);
	rr->NATinfo.Protocol       = protocol;
	rr->NATinfo.IntPort        = rr->resrec.rdata->u.srv.port;
	rr->NATinfo.RequestedPort  = rr->resrec.rdata->u.srv.port;
	rr->NATinfo.NATLease       = 0;		// Request default lease
	rr->NATinfo.clientCallback = CompleteRecordNatMap;
	rr->NATinfo.clientContext  = rr;
	mDNS_StartNATOperation_internal(m, &rr->NATinfo);
	}

// Unlink an Auth Record from the m->ResourceRecords list.
// When a resource record enters regState_NoTarget initially, mDNS_Register_internal
// does not initialize completely e.g., it cannot check for duplicates etc. The resource
// record is temporarily left in the ResourceRecords list so that we can initialize later
// when the target is resolvable. Similarly, when host name changes, we enter regState_NoTarget
// and we do the same.
mDNSlocal mStatus UnlinkResourceRecord(mDNS *const m, AuthRecord *const rr)
	{
	AuthRecord **list = &m->ResourceRecords;
	while (*list && *list != rr) list = &(*list)->next;
	if (*list)
		{
		*list = rr->next;
		rr->next = mDNSNULL;
		return(mStatus_NoError);
		}
	LogMsg("UnlinkResourceRecord:ERROR!! - no such active record %##s", rr->resrec.name->c);
	return(mStatus_NoSuchRecord);
	}

// We need to go through mDNS_Register again as we did not complete the 
// full initialization last time e.g., duplicate checks.
// After we register, we will be in regState_GetZoneData.
mDNSlocal void RegisterAllServiceRecords(mDNS *const m, AuthRecord *rr)
	{
	LogInfo("RegisterAllServiceRecords: Service Record %##s", rr->resrec.name->c);
	// First Register the service record, we do this differently from other records because
	// when it entered NoTarget state, it did not go through complete initialization
	rr->SRVChanged = mDNSfalse;
	UnlinkResourceRecord(m, rr);
	mDNS_Register_internal(m, rr);
	// Register the other records
	UpdateAllServiceRecords(m, rr, mDNStrue);
	}

// Called with lock held
mDNSlocal void UpdateOneSRVRecord(mDNS *m, AuthRecord *rr)
	{
	// Target change if:
	// We have a target and were previously waiting for one, or
	// We had a target and no longer do, or
	// The target has changed

	domainname *curtarget = &rr->resrec.rdata->u.srv.target;
	const domainname *const nt = GetServiceTarget(m, rr);
	const domainname *const newtarget = nt ? nt : (domainname*)"";
	mDNSBool TargetChanged = (newtarget->c[0] && rr->state == regState_NoTarget) || !SameDomainName(curtarget, newtarget);
	mDNSBool HaveZoneData  = rr->nta && !mDNSIPv4AddressIsZero(rr->nta->Addr.ip.v4);

	// Nat state change if:
	// We were behind a NAT, and now we are behind a new NAT, or
	// We're not behind a NAT but our port was previously mapped to a different external port
	// We were not behind a NAT and now we are

	mDNSIPPort port        = rr->resrec.rdata->u.srv.port;
	mDNSBool NowNeedNATMAP = (rr->AutoTarget == Target_AutoHostAndNATMAP && !mDNSIPPortIsZero(port) && mDNSv4AddrIsRFC1918(&m->AdvertisedV4.ip.v4) && rr->nta && !mDNSAddrIsRFC1918(&rr->nta->Addr));
	mDNSBool WereBehindNAT = (rr->NATinfo.clientContext != mDNSNULL);
	mDNSBool PortWasMapped = (rr->NATinfo.clientContext && !mDNSSameIPPort(rr->NATinfo.RequestedPort, port));		// I think this is always false -- SC Sept 07
	mDNSBool NATChanged    = (!WereBehindNAT && NowNeedNATMAP) || (!NowNeedNATMAP && PortWasMapped);

	(void)HaveZoneData; //unused

	LogInfo("UpdateOneSRVRecord: Resource Record %s TargetChanged %d, NewTarget %##s", ARDisplayString(m, rr), TargetChanged, nt->c);

	debugf("UpdateOneSRVRecord: %##s newtarget %##s TargetChanged %d HaveZoneData %d port %d NowNeedNATMAP %d WereBehindNAT %d PortWasMapped %d NATChanged %d",
		rr->resrec.name->c, newtarget,
		TargetChanged, HaveZoneData, mDNSVal16(port), NowNeedNATMAP, WereBehindNAT, PortWasMapped, NATChanged);

	if (m->mDNS_busy != m->mDNS_reentrancy+1)
		LogMsg("UpdateOneSRVRecord: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);

	if (!TargetChanged && !NATChanged) return;

	// If we are deregistering the record, then ignore any NAT/Target change.
	if (rr->resrec.RecordType == kDNSRecordTypeDeregistering)
		{
		LogInfo("UpdateOneSRVRecord: Deregistering record, Ignoring TargetChanged %d, NATChanged %d for %##s, state %d", TargetChanged, NATChanged,
			rr->resrec.name->c, rr->state);
		return;
		}

	if (newtarget)
		LogInfo("UpdateOneSRVRecord: TargetChanged %d, NATChanged %d for %##s, state %d, newtarget %##s", TargetChanged, NATChanged, rr->resrec.name->c, rr->state, newtarget->c);
	else
		LogInfo("UpdateOneSRVRecord: TargetChanged %d, NATChanged %d for %##s, state %d, null newtarget", TargetChanged, NATChanged, rr->resrec.name->c, rr->state);
	switch(rr->state)
		{
		case regState_NATMap:
			// In these states, the SRV has either not yet been registered (it will get up-to-date information when it is)
			// or is in the process of, or has already been, deregistered. This assumes that whenever we transition out
			// of this state, we need to look at the target again.
			return;

		case regState_UpdatePending:
			// We are getting a Target change/NAT change while the SRV record is being updated ?
			// let us not do anything for now.
			return;

		case regState_NATError:
			if (!NATChanged) return;
			// if nat changed, register if we have a target (below)

		case regState_NoTarget:
			if (!newtarget->c[0])
				{
				LogInfo("UpdateOneSRVRecord: No target yet for Resource Record %s", ARDisplayString(m, rr));
				return;
				}
			RegisterAllServiceRecords(m , rr);
			return;
		case regState_DeregPending:
			// We are in DeregPending either because the service was deregistered from above or we handled
			// a NAT/Target change before and sent the deregistration below. There are a few race conditions
			// possible
			//
			// 1. We are handling a second NAT/Target change while the first dereg is in progress. It is possible
			//    that first dereg never made it through because there was no network connectivity e.g., disconnecting
			//    from network triggers this function due to a target change and later connecting to the network
			//    retriggers this function but the deregistration never made it through yet. Just fall through.
			//    If there is a target register otherwise deregister.
			//
			// 2. While we sent the dereg during a previous NAT/Target change, uDNS_DeregisterRecord gets
			//    called as part of service deregistration. When the response comes back, we call
			//    CompleteDeregistration rather than handle NAT/Target change because the record is in
			//    kDNSRecordTypeDeregistering state.
			//
			// 3. If the upper layer deregisters the service, we check for kDNSRecordTypeDeregistering both
			//    here in this function to avoid handling NAT/Target change and in hndlRecordUpdateReply to call
			//    CompleteDeregistration instead of handling NAT/Target change. Hence, we are not concerned
			//    about that case here.
			//
			// We just handle case (1) by falling through
		case regState_Pending:
		case regState_Refresh:
		case regState_Registered:
			// target or nat changed.  deregister service.  upon completion, we'll look for a new target
			rr->SRVChanged = mDNStrue;
			rr->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
			rr->LastAPTime = m->timenow - INIT_RECORD_REG_INTERVAL;
			if (newtarget->c[0])
				{
				LogInfo("UpdateOneSRVRecord: SRV record changed for service %##s, registering with new target %##s",
					rr->resrec.name->c, newtarget->c);
				rr->state = regState_Pending;
				}
			else
				{
				LogInfo("UpdateOneSRVRecord: SRV record changed for service %##s de-registering", rr->resrec.name->c);
				rr->state = regState_DeregPending;
				UpdateAllServiceRecords(m, rr, mDNSfalse);
				}
			return;
		case regState_Unregistered:
		default: LogMsg("UpdateOneSRVRecord: Unknown state %d for %##s", rr->state, rr->resrec.name->c);
		}
	}

mDNSexport void UpdateAllSRVRecords(mDNS *m)
	{
	m->NextSRVUpdate = 0;
	LogInfo("UpdateAllSRVRecords %d", m->SleepState);

	if (m->CurrentRecord)
		LogMsg("UpdateAllSRVRecords ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
	m->CurrentRecord = m->ResourceRecords;
	while (m->CurrentRecord)
		{
		AuthRecord *rptr = m->CurrentRecord;
		m->CurrentRecord = m->CurrentRecord->next;
		if (AuthRecord_uDNS(rptr) && rptr->resrec.rrtype == kDNSType_SRV)
			UpdateOneSRVRecord(m, rptr);
		}
	}

// Forward reference: AdvertiseHostname references HostnameCallback, and HostnameCallback calls AdvertiseHostname
mDNSlocal void HostnameCallback(mDNS *const m, AuthRecord *const rr, mStatus result);

// Called in normal client context (lock not held)
mDNSlocal void hostnameGetPublicAddressCallback(mDNS *m, NATTraversalInfo *n)
	{
	HostnameInfo *h = (HostnameInfo *)n->clientContext;

	if (!h) { LogMsg("RegisterHostnameRecord: registration cancelled"); return; }

	if (!n->Result)
		{
		if (mDNSIPv4AddressIsZero(n->ExternalAddress) || mDNSv4AddrIsRFC1918(&n->ExternalAddress)) return;
		
		if (h->arv4.resrec.RecordType)
			{
			if (mDNSSameIPv4Address(h->arv4.resrec.rdata->u.ipv4, n->ExternalAddress)) return;	// If address unchanged, do nothing
			LogInfo("Updating hostname %p %##s IPv4 from %.4a to %.4a (NAT gateway's external address)",n,
				h->arv4.resrec.name->c, &h->arv4.resrec.rdata->u.ipv4, &n->ExternalAddress);
			mDNS_Deregister(m, &h->arv4);	// mStatus_MemFree callback will re-register with new address
			}
		else
			{
			LogInfo("Advertising hostname %##s IPv4 %.4a (NAT gateway's external address)", h->arv4.resrec.name->c, &n->ExternalAddress);
			h->arv4.resrec.RecordType = kDNSRecordTypeKnownUnique;
			h->arv4.resrec.rdata->u.ipv4 = n->ExternalAddress;
			mDNS_Register(m, &h->arv4);
			}
		}
	}

// register record or begin NAT traversal
mDNSlocal void AdvertiseHostname(mDNS *m, HostnameInfo *h)
	{
	if (!mDNSIPv4AddressIsZero(m->AdvertisedV4.ip.v4) && h->arv4.resrec.RecordType == kDNSRecordTypeUnregistered)
		{
		mDNS_SetupResourceRecord(&h->arv4, mDNSNULL, mDNSInterface_Any, kDNSType_A, kHostNameTTL, kDNSRecordTypeUnregistered, HostnameCallback, h);
		AssignDomainName(&h->arv4.namestorage, &h->fqdn);
		h->arv4.resrec.rdata->u.ipv4 = m->AdvertisedV4.ip.v4;
		h->arv4.state = regState_Unregistered;
		if (mDNSv4AddrIsRFC1918(&m->AdvertisedV4.ip.v4))
			{
			// If we already have a NAT query active, stop it and restart it to make sure we get another callback
			if (h->natinfo.clientContext) mDNS_StopNATOperation_internal(m, &h->natinfo);
			h->natinfo.Protocol         = 0;
			h->natinfo.IntPort          = zeroIPPort;
			h->natinfo.RequestedPort    = zeroIPPort;
			h->natinfo.NATLease         = 0;
			h->natinfo.clientCallback   = hostnameGetPublicAddressCallback;
			h->natinfo.clientContext    = h;
			mDNS_StartNATOperation_internal(m, &h->natinfo);
			}
		else
			{
			LogInfo("Advertising hostname %##s IPv4 %.4a", h->arv4.resrec.name->c, &m->AdvertisedV4.ip.v4);
			h->arv4.resrec.RecordType = kDNSRecordTypeKnownUnique;
			mDNS_Register_internal(m, &h->arv4);
			}
		}

	if (!mDNSIPv6AddressIsZero(m->AdvertisedV6.ip.v6) && h->arv6.resrec.RecordType == kDNSRecordTypeUnregistered)
		{
		mDNS_SetupResourceRecord(&h->arv6, mDNSNULL, mDNSInterface_Any, kDNSType_AAAA, kHostNameTTL, kDNSRecordTypeKnownUnique, HostnameCallback, h);
		AssignDomainName(&h->arv6.namestorage, &h->fqdn);
		h->arv6.resrec.rdata->u.ipv6 = m->AdvertisedV6.ip.v6;
		h->arv6.state = regState_Unregistered;
		LogInfo("Advertising hostname %##s IPv6 %.16a", h->arv6.resrec.name->c, &m->AdvertisedV6.ip.v6);
		mDNS_Register_internal(m, &h->arv6);
		}
	}

mDNSlocal void HostnameCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
	{
	HostnameInfo *hi = (HostnameInfo *)rr->RecordContext;

	if (result == mStatus_MemFree)
		{
		if (hi)
			{
			// If we're still in the Hostnames list, update to new address
			HostnameInfo *i;
			LogInfo("HostnameCallback: Got mStatus_MemFree for %p %p %s", hi, rr, ARDisplayString(m, rr));
			for (i = m->Hostnames; i; i = i->next)
				if (rr == &i->arv4 || rr == &i->arv6)
					{ mDNS_Lock(m); AdvertiseHostname(m, i); mDNS_Unlock(m); return; }

			// Else, we're not still in the Hostnames list, so free the memory
			if (hi->arv4.resrec.RecordType == kDNSRecordTypeUnregistered &&
				hi->arv6.resrec.RecordType == kDNSRecordTypeUnregistered)
				{
				if (hi->natinfo.clientContext) mDNS_StopNATOperation_internal(m, &hi->natinfo);
				hi->natinfo.clientContext = mDNSNULL;
				mDNSPlatformMemFree(hi);	// free hi when both v4 and v6 AuthRecs deallocated
				}
			}
		return;
		}

	if (result)
		{
		// don't unlink or free - we can retry when we get a new address/router
		if (rr->resrec.rrtype == kDNSType_A)
			LogMsg("HostnameCallback: Error %d for registration of %##s IP %.4a", result, rr->resrec.name->c, &rr->resrec.rdata->u.ipv4);
		else
			LogMsg("HostnameCallback: Error %d for registration of %##s IP %.16a", result, rr->resrec.name->c, &rr->resrec.rdata->u.ipv6);
		if (!hi) { mDNSPlatformMemFree(rr); return; }
		if (rr->state != regState_Unregistered) LogMsg("Error: HostnameCallback invoked with error code for record not in regState_Unregistered!");

		if (hi->arv4.state == regState_Unregistered &&
			hi->arv6.state == regState_Unregistered)
			{
			// only deliver status if both v4 and v6 fail
			rr->RecordContext = (void *)hi->StatusContext;
			if (hi->StatusCallback)
				hi->StatusCallback(m, rr, result); // client may NOT make API calls here
			rr->RecordContext = (void *)hi;
			}
		return;
		}

	// register any pending services that require a target
	mDNS_Lock(m);
	m->NextSRVUpdate = NonZeroTime(m->timenow);
	mDNS_Unlock(m);

	// Deliver success to client
	if (!hi) { LogMsg("HostnameCallback invoked with orphaned address record"); return; }
	if (rr->resrec.rrtype == kDNSType_A)
		LogInfo("Registered hostname %##s IP %.4a", rr->resrec.name->c, &rr->resrec.rdata->u.ipv4);
	else
		LogInfo("Registered hostname %##s IP %.16a", rr->resrec.name->c, &rr->resrec.rdata->u.ipv6);

	rr->RecordContext = (void *)hi->StatusContext;
	if (hi->StatusCallback)
		hi->StatusCallback(m, rr, result); // client may NOT make API calls here
	rr->RecordContext = (void *)hi;
	}

mDNSlocal void FoundStaticHostname(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
	{
	const domainname *pktname = &answer->rdata->u.name;
	domainname *storedname = &m->StaticHostname;
	HostnameInfo *h = m->Hostnames;

	(void)question;

	if (answer->rdlength != 0)
		LogInfo("FoundStaticHostname: question %##s -> answer %##s (%s)", question->qname.c, answer->rdata->u.name.c, AddRecord ? "ADD" : "RMV");
	else
		LogInfo("FoundStaticHostname: question %##s -> answer NULL (%s)", question->qname.c, AddRecord ? "ADD" : "RMV");

	if (AddRecord && answer->rdlength != 0 && !SameDomainName(pktname, storedname))
		{
		AssignDomainName(storedname, pktname);
		while (h)
			{
			if (h->arv4.state == regState_Pending || h->arv4.state == regState_NATMap || h->arv6.state == regState_Pending)
				{
				// if we're in the process of registering a dynamic hostname, delay SRV update so we don't have to reregister services if the dynamic name succeeds
				m->NextSRVUpdate = NonZeroTime(m->timenow + 5 * mDNSPlatformOneSecond);
				debugf("FoundStaticHostname: NextSRVUpdate in %d %d", m->NextSRVUpdate - m->timenow, m->timenow);
				return;
				}
			h = h->next;
			}
		mDNS_Lock(m);
		m->NextSRVUpdate = NonZeroTime(m->timenow);
		mDNS_Unlock(m);
		}
	else if (!AddRecord && SameDomainName(pktname, storedname))
		{
		mDNS_Lock(m);
		storedname->c[0] = 0;
		m->NextSRVUpdate = NonZeroTime(m->timenow);
		mDNS_Unlock(m);
		}
	}

// Called with lock held
mDNSlocal void GetStaticHostname(mDNS *m)
	{
	char buf[MAX_REVERSE_MAPPING_NAME_V4];
	DNSQuestion *q = &m->ReverseMap;
	mDNSu8 *ip = m->AdvertisedV4.ip.v4.b;
	mStatus err;

	if (m->ReverseMap.ThisQInterval != -1) return; // already running
	if (mDNSIPv4AddressIsZero(m->AdvertisedV4.ip.v4)) return;

	mDNSPlatformMemZero(q, sizeof(*q));
	// Note: This is reverse order compared to a normal dotted-decimal IP address, so we can't use our customary "%.4a" format code
	mDNS_snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa.", ip[3], ip[2], ip[1], ip[0]);
	if (!MakeDomainNameFromDNSNameString(&q->qname, buf)) { LogMsg("Error: GetStaticHostname - bad name %s", buf); return; }

	q->InterfaceID      = mDNSInterface_Any;
	q->Target           = zeroAddr;
	q->qtype            = kDNSType_PTR;
	q->qclass           = kDNSClass_IN;
	q->LongLived        = mDNSfalse;
	q->ExpectUnique     = mDNSfalse;
	q->ForceMCast       = mDNSfalse;
	q->ReturnIntermed   = mDNStrue;
	q->SuppressUnusable = mDNSfalse;
	q->QuestionCallback = FoundStaticHostname;
	q->QuestionContext  = mDNSNULL;

	LogInfo("GetStaticHostname: %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
	err = mDNS_StartQuery_internal(m, q);
	if (err) LogMsg("Error: GetStaticHostname - StartQuery returned error %d", err);
	}

mDNSexport void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCallback *StatusCallback, const void *StatusContext)
   {
	HostnameInfo **ptr = &m->Hostnames;

	LogInfo("mDNS_AddDynDNSHostName %##s", fqdn);

	while (*ptr && !SameDomainName(fqdn, &(*ptr)->fqdn)) ptr = &(*ptr)->next;
	if (*ptr) { LogMsg("DynDNSHostName %##s already in list", fqdn->c); return; }

	// allocate and format new address record
	*ptr = mDNSPlatformMemAllocate(sizeof(**ptr));
	if (!*ptr) { LogMsg("ERROR: mDNS_AddDynDNSHostName - malloc"); return; }

	mDNSPlatformMemZero(*ptr, sizeof(**ptr));
	AssignDomainName(&(*ptr)->fqdn, fqdn);
	(*ptr)->arv4.state     = regState_Unregistered;
	(*ptr)->arv6.state     = regState_Unregistered;
	(*ptr)->StatusCallback = StatusCallback;
	(*ptr)->StatusContext  = StatusContext;

	AdvertiseHostname(m, *ptr);
	}

mDNSexport void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn)
	{
	HostnameInfo **ptr = &m->Hostnames;

	LogInfo("mDNS_RemoveDynDNSHostName %##s", fqdn);

	while (*ptr && !SameDomainName(fqdn, &(*ptr)->fqdn)) ptr = &(*ptr)->next;
	if (!*ptr) LogMsg("mDNS_RemoveDynDNSHostName: no such domainname %##s", fqdn->c);
	else
		{
		HostnameInfo *hi = *ptr;
		// We do it this way because, if we have no active v6 record, the "mDNS_Deregister_internal(m, &hi->arv4);"
		// below could free the memory, and we have to make sure we don't touch hi fields after that.
		mDNSBool f4 = hi->arv4.resrec.RecordType != kDNSRecordTypeUnregistered && hi->arv4.state != regState_Unregistered;
		mDNSBool f6 = hi->arv6.resrec.RecordType != kDNSRecordTypeUnregistered && hi->arv6.state != regState_Unregistered;
		if (f4) LogInfo("mDNS_RemoveDynDNSHostName removing v4 %##s", fqdn);
		if (f6) LogInfo("mDNS_RemoveDynDNSHostName removing v6 %##s", fqdn);
		*ptr = (*ptr)->next; // unlink
		if (f4) mDNS_Deregister_internal(m, &hi->arv4, mDNS_Dereg_normal);
		if (f6) mDNS_Deregister_internal(m, &hi->arv6, mDNS_Dereg_normal);
		// When both deregistrations complete we'll free the memory in the mStatus_MemFree callback
		}
	if (!m->mDNS_busy) LogMsg("mDNS_RemoveDynDNSHostName: ERROR: Lock not held");
	m->NextSRVUpdate = NonZeroTime(m->timenow);
	}

// Currently called without holding the lock
// Maybe we should change that?
mDNSexport void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, const mDNSAddr *v6addr, const mDNSAddr *router)
	{
	mDNSBool v4Changed, v6Changed, RouterChanged;

	if (m->mDNS_busy != m->mDNS_reentrancy)
		LogMsg("mDNS_SetPrimaryInterfaceInfo: mDNS_busy (%ld) != mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);

	if (v4addr && v4addr->type != mDNSAddrType_IPv4) { LogMsg("mDNS_SetPrimaryInterfaceInfo v4 address - incorrect type.  Discarding. %#a", v4addr); return; }
	if (v6addr && v6addr->type != mDNSAddrType_IPv6) { LogMsg("mDNS_SetPrimaryInterfaceInfo v6 address - incorrect type.  Discarding. %#a", v6addr); return; }
	if (router && router->type != mDNSAddrType_IPv4) { LogMsg("mDNS_SetPrimaryInterfaceInfo passed non-v4 router.  Discarding. %#a",        router); return; }

	mDNS_Lock(m);

	v4Changed     = !mDNSSameIPv4Address(m->AdvertisedV4.ip.v4, v4addr ? v4addr->ip.v4 : zerov4Addr);
	v6Changed     = !mDNSSameIPv6Address(m->AdvertisedV6.ip.v6, v6addr ? v6addr->ip.v6 : zerov6Addr);
	RouterChanged = !mDNSSameIPv4Address(m->Router.ip.v4,       router ? router->ip.v4 : zerov4Addr);

	if (v4addr && (v4Changed || RouterChanged))
		debugf("mDNS_SetPrimaryInterfaceInfo: address changed from %#a to %#a", &m->AdvertisedV4, v4addr);

	if (v4addr) m->AdvertisedV4 = *v4addr; else m->AdvertisedV4.ip.v4 = zerov4Addr;
	if (v6addr) m->AdvertisedV6 = *v6addr; else m->AdvertisedV6.ip.v6 = zerov6Addr;
	if (router) m->Router       = *router; else m->Router      .ip.v4 = zerov4Addr;
	// setting router to zero indicates that nat mappings must be reestablished when router is reset

	if (v4Changed || RouterChanged || v6Changed)
		{
		HostnameInfo *i;
		LogInfo("mDNS_SetPrimaryInterfaceInfo: %s%s%s%#a %#a %#a",
			v4Changed     ? "v4Changed "     : "",
			RouterChanged ? "RouterChanged " : "",
			v6Changed     ? "v6Changed "     : "", v4addr, v6addr, router);

		for (i = m->Hostnames; i; i = i->next)
			{
			LogInfo("mDNS_SetPrimaryInterfaceInfo updating host name registrations for %##s", i->fqdn.c);
	
			if (i->arv4.resrec.RecordType > kDNSRecordTypeDeregistering &&
				!mDNSSameIPv4Address(i->arv4.resrec.rdata->u.ipv4, m->AdvertisedV4.ip.v4))
				{
				LogInfo("mDNS_SetPrimaryInterfaceInfo deregistering %s", ARDisplayString(m, &i->arv4));
				mDNS_Deregister_internal(m, &i->arv4, mDNS_Dereg_normal);
				}
	
			if (i->arv6.resrec.RecordType > kDNSRecordTypeDeregistering &&
				!mDNSSameIPv6Address(i->arv6.resrec.rdata->u.ipv6, m->AdvertisedV6.ip.v6))
				{
				LogInfo("mDNS_SetPrimaryInterfaceInfo deregistering %s", ARDisplayString(m, &i->arv6));
				mDNS_Deregister_internal(m, &i->arv6, mDNS_Dereg_normal);
				}

			// AdvertiseHostname will only register new address records.
			// For records still in the process of deregistering it will ignore them, and let the mStatus_MemFree callback handle them.
			AdvertiseHostname(m, i);
			}

		if (v4Changed || RouterChanged)
			{
			// If we have a non-zero IPv4 address, we should try immediately to see if we have a NAT gateway
			// If we have no IPv4 address, we don't want to be in quite such a hurry to report failures to our clients
			// <rdar://problem/6935929> Sleeping server sometimes briefly disappears over Back to My Mac after it wakes up
			m->ExternalAddress      = zerov4Addr;
			m->retryIntervalGetAddr = NATMAP_INIT_RETRY;
			m->retryGetAddr         = m->timenow + (v4addr ? 0 : mDNSPlatformOneSecond * 5);
			m->NextScheduledNATOp   = m->timenow;
			m->LastNATMapResultCode = NATErr_None;
#ifdef _LEGACY_NAT_TRAVERSAL_
			LNT_ClearState(m);
#endif // _LEGACY_NAT_TRAVERSAL_
			LogInfo("mDNS_SetPrimaryInterfaceInfo:%s%s: retryGetAddr in %d %d",
				v4Changed     ? " v4Changed"     : "",
				RouterChanged ? " RouterChanged" : "",
				m->retryGetAddr - m->timenow, m->timenow);
			}

		if (m->ReverseMap.ThisQInterval != -1) mDNS_StopQuery_internal(m, &m->ReverseMap);
		m->StaticHostname.c[0] = 0;
		
		m->NextSRVUpdate = NonZeroTime(m->timenow);
		
#if APPLE_OSX_mDNSResponder
		if (RouterChanged)	uuid_generate(m->asl_uuid);
		UpdateAutoTunnelDomainStatuses(m);
#endif
		}

	mDNS_Unlock(m);
	}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - Incoming Message Processing
#endif

mDNSlocal mStatus ParseTSIGError(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, const domainname *const displayname)
	{
	const mDNSu8 *ptr;
	mStatus err = mStatus_NoError;
	int i;

	ptr = LocateAdditionals(msg, end);
	if (!ptr) goto finish;

	for (i = 0; i < msg->h.numAdditionals; i++)
		{
		ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
		if (!ptr) goto finish;
		if (m->rec.r.resrec.RecordType != kDNSRecordTypePacketNegative && m->rec.r.resrec.rrtype == kDNSType_TSIG)
			{
			mDNSu32 macsize;
			mDNSu8 *rd = m->rec.r.resrec.rdata->u.data;
			mDNSu8 *rdend = rd + m->rec.r.resrec.rdlength;
			int alglen = DomainNameLengthLimit(&m->rec.r.resrec.rdata->u.name, rdend);
			if (alglen > MAX_DOMAIN_NAME) goto finish;
			rd += alglen;                                       // algorithm name
			if (rd + 6 > rdend) goto finish;
			rd += 6;                                            // 48-bit timestamp
			if (rd + sizeof(mDNSOpaque16) > rdend) goto finish;
			rd += sizeof(mDNSOpaque16);                         // fudge
			if (rd + sizeof(mDNSOpaque16) > rdend) goto finish;
			macsize = mDNSVal16(*(mDNSOpaque16 *)rd);
			rd += sizeof(mDNSOpaque16);                         // MAC size
			if (rd + macsize > rdend) goto finish;
			rd += macsize;
			if (rd + sizeof(mDNSOpaque16) > rdend) goto finish;
			rd += sizeof(mDNSOpaque16);                         // orig id
			if (rd + sizeof(mDNSOpaque16) > rdend) goto finish;
			err = mDNSVal16(*(mDNSOpaque16 *)rd);               // error code

			if      (err == TSIG_ErrBadSig)  { LogMsg("%##s: bad signature", displayname->c);              err = mStatus_BadSig;     }
			else if (err == TSIG_ErrBadKey)  { LogMsg("%##s: bad key", displayname->c);                    err = mStatus_BadKey;     }
			else if (err == TSIG_ErrBadTime) { LogMsg("%##s: bad time", displayname->c);                   err = mStatus_BadTime;    }
			else if (err)                    { LogMsg("%##s: unknown tsig error %d", displayname->c, err); err = mStatus_UnknownErr; }
			goto finish;
			}
		m->rec.r.resrec.RecordType = 0;		// Clear RecordType to show we're not still using it
		}

	finish:
	m->rec.r.resrec.RecordType = 0;		// Clear RecordType to show we're not still using it
	return err;
	}

mDNSlocal mStatus checkUpdateResult(mDNS *const m, const domainname *const displayname, const mDNSu8 rcode, const DNSMessage *const msg, const mDNSu8 *const end)
	{
	(void)msg;	// currently unused, needed for TSIG errors
	if (!rcode) return mStatus_NoError;
	else if (rcode == kDNSFlag1_RC_YXDomain)
		{
		debugf("name in use: %##s", displayname->c);
		return mStatus_NameConflict;
		}
	else if (rcode == kDNSFlag1_RC_Refused)
		{
		LogMsg("Update %##s refused", displayname->c);
		return mStatus_Refused;
		}
	else if (rcode == kDNSFlag1_RC_NXRRSet)
		{
		LogMsg("Reregister refused (NXRRSET): %##s", displayname->c);
		return mStatus_NoSuchRecord;
		}
	else if (rcode == kDNSFlag1_RC_NotAuth)
		{
		// TSIG errors should come with FormErr as per RFC 2845, but BIND 9 sends them with NotAuth so we look here too
		mStatus tsigerr = ParseTSIGError(m, msg, end, displayname);
		if (!tsigerr)
			{
			LogMsg("Permission denied (NOAUTH): %##s", displayname->c);
			return mStatus_UnknownErr;
			}
		else return tsigerr;
		}
	else if (rcode == kDNSFlag1_RC_FormErr)
		{
		mStatus tsigerr = ParseTSIGError(m, msg, end, displayname);
		if (!tsigerr)
			{
			LogMsg("Format Error: %##s", displayname->c);
			return mStatus_UnknownErr;
			}
		else return tsigerr;
		}
	else
		{
		LogMsg("Update %##s failed with rcode %d", displayname->c, rcode);
		return mStatus_UnknownErr;
		}
	}

// We add three Additional Records for unicast resource record registrations
// which is a function of AuthInfo and AutoTunnel properties
mDNSlocal mDNSu32 RRAdditionalSize(mDNS *const m, DomainAuthInfo *AuthInfo)
	{
	mDNSu32 leaseSize, hinfoSize, tsigSize;
	mDNSu32 rr_base_size = 10; // type (2) class (2) TTL (4) rdlength (2)

	// OPT RR : Emptyname(.) + base size + rdataOPT
	leaseSize = 1 + rr_base_size + sizeof(rdataOPT);

	// HINFO: Resource Record Name + base size + RDATA
	// HINFO is added only for autotunnels
	hinfoSize = 0;
	if (AuthInfo && AuthInfo->AutoTunnel)
		hinfoSize = (m->hostlabel.c[0] + 1) + DomainNameLength(&AuthInfo->domain) +
			rr_base_size + (2 + m->HIHardware.c[0] + m->HISoftware.c[0]);

	//TSIG: Resource Record Name + base size + RDATA
	// RDATA:
    // 	Algorithm name: hmac-md5.sig-alg.reg.int (8+7+3+3 + 5 bytes for length = 26 bytes)
    // 	Time: 6 bytes
	// 	Fudge: 2 bytes
    // 	Mac Size: 2 bytes
	// 	Mac: 16 bytes
	// 	ID: 2 bytes
    // 	Error: 2 bytes
    // 	Len: 2 bytes
	// 	Total: 58 bytes 
	tsigSize = 0;
	if (AuthInfo) tsigSize = DomainNameLength(&AuthInfo->keyname) + rr_base_size + 58;

	return (leaseSize + hinfoSize + tsigSize);
	}

//Note: Make sure that RREstimatedSize is updated accordingly if anything that is done here
//would modify rdlength/rdestimate
mDNSlocal mDNSu8* BuildUpdateMessage(mDNS *const m, mDNSu8 *ptr, AuthRecord *rr, mDNSu8 *limit)
	{
	//If this record is deregistering, then just send the deletion record
	if (rr->state == regState_DeregPending)
		{
		rr->expire = 0;		// Indicate that we have no active registration any more
		ptr = putDeletionRecordWithLimit(&m->omsg, ptr, &rr->resrec, limit);
		if (!ptr) goto exit;
		return ptr;
		}

	// This is a common function to both sending an update in a group or individual
	// records separately. Hence, we change the state here.
	if (rr->state == regState_Registered) rr->state = regState_Refresh;
	if (rr->state != regState_Refresh && rr->state != regState_UpdatePending)
		rr->state = regState_Pending;

	// For Advisory records like e.g., _services._dns-sd, which is shared, don't send goodbyes as multiple
	// host might be registering records and deregistering from one does not make sense
	if (rr->resrec.RecordType != kDNSRecordTypeAdvisory) rr->RequireGoodbye = mDNStrue;

	if ((rr->resrec.rrtype == kDNSType_SRV) && (rr->AutoTarget == Target_AutoHostAndNATMAP) &&
		!mDNSIPPortIsZero(rr->NATinfo.ExternalPort))
		{
		rr->resrec.rdata->u.srv.port = rr->NATinfo.ExternalPort;
		}

	if (rr->state == regState_UpdatePending)
		{
		// delete old RData
		SetNewRData(&rr->resrec, rr->OrigRData, rr->OrigRDLen);
		if (!(ptr = putDeletionRecordWithLimit(&m->omsg, ptr, &rr->resrec, limit))) goto exit; // delete old rdata

		// add new RData
		SetNewRData(&rr->resrec, rr->InFlightRData, rr->InFlightRDLen);
		if (!(ptr = PutResourceRecordTTLWithLimit(&m->omsg, ptr, &m->omsg.h.mDNS_numUpdates, &rr->resrec, rr->resrec.rroriginalttl, limit)))  goto exit;
		}
	else
		{
		if (rr->resrec.RecordType == kDNSRecordTypeKnownUnique || rr->resrec.RecordType == kDNSRecordTypeVerified)
			{
			// KnownUnique : Delete any previous value 
			// For Unicast registrations, we don't verify that it is unique, but set to verified and hence we want to
			// delete any previous value
			ptr = putDeleteRRSetWithLimit(&m->omsg, ptr, rr->resrec.name, rr->resrec.rrtype, limit);
			if (!ptr) goto exit;
			}
		else if (rr->resrec.RecordType != kDNSRecordTypeShared)
			{
			// For now don't do this, until we have the logic for intelligent grouping of individual records into logical service record sets
			//ptr = putPrereqNameNotInUse(rr->resrec.name, &m->omsg, ptr, end);
			if (!ptr) goto exit;
			}

		ptr = PutResourceRecordTTLWithLimit(&m->omsg, ptr, &m->omsg.h.mDNS_numUpdates, &rr->resrec, rr->resrec.rroriginalttl, limit);
		if (!ptr) goto exit;
		}

	return ptr;
exit:
	LogMsg("BuildUpdateMessage: Error formatting message for %s", ARDisplayString(m, rr));
	return mDNSNULL;
	}

// Called with lock held
mDNSlocal void SendRecordRegistration(mDNS *const m, AuthRecord *rr)
	{
	mDNSu8 *ptr = m->omsg.data;
	mStatus err = mStatus_UnknownErr;
	mDNSu8 *limit;
	DomainAuthInfo *AuthInfo;

	// For the ability to register large TXT records, we limit the single record registrations
	// to AbsoluteMaxDNSMessageData
	limit = ptr + AbsoluteMaxDNSMessageData;

	AuthInfo = GetAuthInfoForName_internal(m, rr->resrec.name);
	limit -= RRAdditionalSize(m, AuthInfo);

	if (m->mDNS_busy != m->mDNS_reentrancy+1)
		LogMsg("SendRecordRegistration: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);

	if (!rr->nta || mDNSIPv4AddressIsZero(rr->nta->Addr.ip.v4))
		{
		// We never call this function when there is no zone information . Log a message if it ever happens.
		LogMsg("SendRecordRegistration: No Zone information, should not happen %s", ARDisplayString(m, rr));
		return;
		}

	rr->updateid = mDNS_NewMessageID(m);
	InitializeDNSMessage(&m->omsg.h, rr->updateid, UpdateReqFlags);

	// set zone
	ptr = putZone(&m->omsg, ptr, limit, rr->zone, mDNSOpaque16fromIntVal(rr->resrec.rrclass));
	if (!ptr) goto exit;

	if (!(ptr = BuildUpdateMessage(m, ptr, rr, limit))) goto exit;

	if (rr->uselease)
		{
		ptr = putUpdateLeaseWithLimit(&m->omsg, ptr, DEFAULT_UPDATE_LEASE, limit);
		if (!ptr) goto exit;
		}
	if (rr->Private)
		{
		LogInfo("SendRecordRegistration TCP %p %s", rr->tcp, ARDisplayString(m, rr));
		if (rr->tcp) LogInfo("SendRecordRegistration: Disposing existing TCP connection for %s", ARDisplayString(m, rr));
		if (rr->tcp) { DisposeTCPConn(rr->tcp); rr->tcp = mDNSNULL; }
		if (!rr->nta) { LogMsg("SendRecordRegistration:Private:ERROR!! nta is NULL for %s", ARDisplayString(m, rr)); return; }
		rr->tcp = MakeTCPConn(m, &m->omsg, ptr, kTCPSocketFlags_UseTLS, &rr->nta->Addr, rr->nta->Port, &rr->nta->Host, mDNSNULL, rr);
		}
	else
		{
		LogInfo("SendRecordRegistration UDP %s", ARDisplayString(m, rr));
		if (!rr->nta) { LogMsg("SendRecordRegistration:ERROR!! nta is NULL for %s", ARDisplayString(m, rr)); return; }
		err = mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, mDNSNULL, &rr->nta->Addr, rr->nta->Port, mDNSNULL, GetAuthInfoForName_internal(m, rr->resrec.name));
		if (err) debugf("ERROR: SendRecordRegistration - mDNSSendDNSMessage - %d", err);
		}

	SetRecordRetry(m, rr, 0);
	return;
exit:
	LogMsg("SendRecordRegistration: Error formatting message for %s, disabling further updates", ARDisplayString(m, rr));
	// Disable this record from future updates
	rr->state = regState_NoTarget;
	}

// Is the given record "rr" eligible for merging ?
mDNSlocal mDNSBool IsRecordMergeable(mDNS *const m, AuthRecord *rr, mDNSs32 time)
	{
	DomainAuthInfo *info;
	(void) m; //unused
	// A record is eligible for merge, if the following properties are met.
	//
	// 1. uDNS Resource Record
	// 2. It is time to send them now
	// 3. It is in proper state
	// 4. Update zone has been resolved
	// 5. if DomainAuthInfo exists for the zone, it should not be soon deleted
	// 6. Zone information is present
	// 7. Update server is not zero
	// 8. It has a non-null zone
	// 9. It uses a lease option 
	// 10. DontMerge is not set
	//
	// Following code is implemented as separate "if" statements instead of one "if" statement
	// is for better debugging purposes e.g., we know exactly what failed if debugging turned on.

	if (!AuthRecord_uDNS(rr)) return mDNSfalse;

	if (rr->LastAPTime + rr->ThisAPInterval - time > 0)
		{ debugf("IsRecordMergeable: Time %d not reached for %s", rr->LastAPTime + rr->ThisAPInterval - m->timenow, ARDisplayString(m, rr)); return mDNSfalse; }

	if (!rr->zone) return mDNSfalse;

	info = GetAuthInfoForName_internal(m, rr->zone);

	if (info && info->deltime && m->timenow - info->deltime >= 0) {debugf("IsRecordMergeable: Domain %##s will be deleted soon", info->domain.c); return mDNSfalse;}

	if (rr->state != regState_DeregPending && rr->state != regState_Pending && rr->state != regState_Registered && rr->state != regState_Refresh && rr->state != regState_UpdatePending)
		{ debugf("IsRecordMergeable: state %d not right  %s", rr->state, ARDisplayString(m, rr)); return mDNSfalse; }

	if (!rr->nta || mDNSIPv4AddressIsZero(rr->nta->Addr.ip.v4)) return mDNSfalse;

	if (!rr->uselease) return mDNSfalse;
	
	if (rr->mState == mergeState_DontMerge) {debugf("IsRecordMergeable Dontmerge true %s", ARDisplayString(m, rr));return mDNSfalse;}
	debugf("IsRecordMergeable: Returning true for %s", ARDisplayString(m, rr));
	return mDNStrue;
	}

// Is the resource record "rr" eligible to merge to with "currentRR" ?
mDNSlocal mDNSBool AreRecordsMergeable(mDNS *const m, AuthRecord *currentRR, AuthRecord *rr, mDNSs32 time)
	{
	// A record is eligible to merge with another record as long it is eligible for merge in itself
	// and it has the same zone information as the other record
	if (!IsRecordMergeable(m, rr, time)) return mDNSfalse;

	if (!SameDomainName(currentRR->zone, rr->zone))
		{ debugf("AreRecordMergeable zone mismatch current rr Zone %##s, rr zone  %##s", currentRR->zone->c, rr->zone->c); return mDNSfalse; }

	if (!mDNSSameIPv4Address(currentRR->nta->Addr.ip.v4, rr->nta->Addr.ip.v4)) return mDNSfalse;

	if (!mDNSSameIPPort(currentRR->nta->Port, rr->nta->Port)) return mDNSfalse;

	debugf("AreRecordsMergeable: Returning true for %s", ARDisplayString(m, rr));
	return mDNStrue;
	}

// If we can't build the message successfully because of problems in pre-computing
// the space, we disable merging for all the current records
mDNSlocal void RRMergeFailure(mDNS *const m)
	{
	AuthRecord *rr;
	for (rr = m->ResourceRecords; rr; rr = rr->next)
		{
		rr->mState = mergeState_DontMerge;
		rr->SendRNow = mDNSNULL;
		// Restarting the registration is much simpler than saving and restoring
		// the exact time
		ActivateUnicastRegistration(m, rr);
		}
	}

mDNSlocal void SendGroupRRMessage(mDNS *const m, AuthRecord *anchorRR, mDNSu8 *ptr, DomainAuthInfo *info)
	{
	mDNSu8 *limit;
	if (!anchorRR) {debugf("SendGroupRRMessage: Could not merge records"); return;}

	if (info && info->AutoTunnel) limit = m->omsg.data + AbsoluteMaxDNSMessageData;
	else limit = m->omsg.data + NormalMaxDNSMessageData;

	// This has to go in the additional section and hence need to be done last
	ptr = putUpdateLeaseWithLimit(&m->omsg, ptr, DEFAULT_UPDATE_LEASE, limit);
	if (!ptr)
		{
		LogMsg("SendGroupRRMessage: ERROR: Could not put lease option, failing the group registration");
		// if we can't put the lease, we need to undo the merge
		RRMergeFailure(m);
		return;
		}
	if (anchorRR->Private)
		{
		if (anchorRR->tcp) debugf("SendGroupRRMessage: Disposing existing TCP connection for %s", ARDisplayString(m, anchorRR));
		if (anchorRR->tcp) { DisposeTCPConn(anchorRR->tcp); anchorRR->tcp = mDNSNULL; }
		if (!anchorRR->nta) { LogMsg("SendGroupRRMessage:ERROR!! nta is NULL for %s", ARDisplayString(m, anchorRR)); return; }
		anchorRR->tcp = MakeTCPConn(m, &m->omsg, ptr, kTCPSocketFlags_UseTLS, &anchorRR->nta->Addr, anchorRR->nta->Port, &anchorRR->nta->Host, mDNSNULL, anchorRR);
		if (!anchorRR->tcp) LogInfo("SendGroupRRMessage: Cannot establish TCP connection for %s", ARDisplayString(m, anchorRR));
		else LogInfo("SendGroupRRMessage: Sent a group update ID: %d start %p, end %p, limit %p", mDNSVal16(m->omsg.h.id), m->omsg.data, ptr, limit);
		}
	else 
		{
		mStatus err = mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, mDNSNULL, &anchorRR->nta->Addr, anchorRR->nta->Port, mDNSNULL, info);
		if (err) LogInfo("SendGroupRRMessage: Cannot send UDP message for %s", ARDisplayString(m, anchorRR));
		else LogInfo("SendGroupRRMessage: Sent a group UDP update ID: %d start %p, end %p, limit %p", mDNSVal16(m->omsg.h.id), m->omsg.data, ptr, limit);
		}
	return;
	}

// As we always include the zone information and the resource records contain zone name
// at the end, it will get compressed. Hence, we subtract zoneSize and add two bytes for
// the compression pointer
mDNSlocal mDNSu32 RREstimatedSize(AuthRecord *rr, int zoneSize)
	{
	int rdlength;

	// Note: Estimation of the record size has to mirror the logic in BuildUpdateMessage, otherwise estimation
	// would be wrong. Currently BuildUpdateMessage calls SetNewRData in UpdatePending case. Hence, we need
	// to account for that here. Otherwise, we might under estimate the size.
	if (rr->state == regState_UpdatePending)
		// old RData that will be deleted
		// new RData that will be added
		rdlength = rr->OrigRDLen + rr->InFlightRDLen;
	else
		rdlength = rr->resrec.rdestimate;

	if (rr->state == regState_DeregPending)
		{
		debugf("RREstimatedSize: ResourceRecord %##s (%s), DomainNameLength %d, zoneSize %d, rdestimate %d",
				rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype), DomainNameLength(rr->resrec.name), zoneSize, rdlength);
		return DomainNameLength(rr->resrec.name) - zoneSize + 2 + 10 + rdlength;
		}

	// For SRV, TXT, AAAA etc. that are Unique/Verified, we also send a Deletion Record
	if (rr->resrec.RecordType == kDNSRecordTypeKnownUnique || rr->resrec.RecordType == kDNSRecordTypeVerified)
		{
		// Deletion Record: Resource Record Name + Base size (10) + 0
		// Record: Resource Record Name (Compressed = 2) + Base size (10) + rdestimate

		debugf("RREstimatedSize: ResourceRecord %##s (%s), DomainNameLength %d, zoneSize %d, rdestimate %d",
				rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype), DomainNameLength(rr->resrec.name), zoneSize, rdlength);
		return DomainNameLength(rr->resrec.name) - zoneSize + 2 + 10 + 2 + 10 + rdlength;
		}
	else
		{
		return DomainNameLength(rr->resrec.name) - zoneSize + 2 + 10 + rdlength;
		}
	}

mDNSlocal AuthRecord *MarkRRForSending(mDNS *const m)
	{
	AuthRecord *rr;
	AuthRecord *firstRR = mDNSNULL;

	// Look for records that needs to be sent in the next two seconds (MERGE_DELAY_TIME is set to 1 second).
	// The logic is as follows.
	//
	// 1. Record 1 finishes getting zone data and its registration gets delayed by 1 second
	// 2. Record 2 comes 0.1 second later, finishes getting its zone data and its registration is also delayed by
	//    1 second which is now scheduled at 1.1 second
	//
	// By looking for 1 second into the future (m->timenow + MERGE_DELAY_TIME below does that) we have merged both
	// of the above records. Note that we can't look for records too much into the future as this will affect the
	// retry logic. The first retry is scheduled at 3 seconds. Hence, we should always look smaller than that.
	// Anything more than one second will affect the first retry to happen sooner. 
	//
	// Note: As a side effect of looking one second into the future to facilitate merging, the retries happen
	// one second sooner.
	for (rr = m->ResourceRecords; rr; rr = rr->next)
		{
		if (!firstRR)
			{
			if (!IsRecordMergeable(m, rr, m->timenow + MERGE_DELAY_TIME)) continue;
			firstRR = rr;
			}
		else if (!AreRecordsMergeable(m, firstRR, rr, m->timenow + MERGE_DELAY_TIME)) continue;

		if (rr->SendRNow) LogMsg("MarkRRForSending: Resourcerecord %s already marked for sending", ARDisplayString(m, rr));
		rr->SendRNow = mDNSInterfaceMark;
		}

	// We parsed through all records and found something to send. The services/records might
	// get registered at different times but we want the refreshes to be all merged and sent
	// as one update. Hence, we accelerate some of the records so that they will sync up in
	// the future. Look at the records excluding the ones that we have already sent in the
	// previous pass. If it half way through its scheduled refresh/retransmit, merge them
	// into this packet.
	//
	// Note that we only look at Registered/Refresh state to keep it simple. As we don't know
	// whether the current update will fit into one or more packets, merging a resource record
	// (which is in a different state) that has been scheduled for retransmit would trigger
	// sending more packets.
	if (firstRR)
		{
		int acc = 0;
		for (rr = m->ResourceRecords; rr; rr = rr->next)
			{
			if ((rr->state != regState_Registered && rr->state != regState_Refresh) ||
				(rr->SendRNow == mDNSInterfaceMark) || 
				(!AreRecordsMergeable(m, firstRR, rr, m->timenow + rr->ThisAPInterval/2)))
				continue;
			rr->SendRNow = mDNSInterfaceMark;
			acc++;
			}
		if (acc) LogInfo("MarkRRForSending: Accelereated %d records", acc);
		}
	return firstRR;
	}

mDNSlocal mDNSBool SendGroupUpdates(mDNS *const m)
	{
	mDNSOpaque16 msgid;
	mDNSs32 spaceleft = 0;
	mDNSs32 zoneSize, rrSize;
	mDNSu8 *oldnext; // for debugging
	mDNSu8 *next = m->omsg.data;
	AuthRecord *rr;
	AuthRecord *anchorRR = mDNSNULL;
	int nrecords = 0;
	AuthRecord *startRR = m->ResourceRecords;
	mDNSu8 *limit = mDNSNULL;
	DomainAuthInfo *AuthInfo = mDNSNULL;
	mDNSBool sentallRecords = mDNStrue;


	// We try to fit as many ResourceRecords as possible in AbsoluteNormal/MaxDNSMessageData. Before we start
	// putting in resource records, we need to reserve space for a few things. Every group/packet should
	// have the following.
	//
	// 1) Needs space for the Zone information (which needs to be at the beginning)
	// 2) Additional section MUST have space for lease option, HINFO and TSIG option (which needs to
	//    to be at the end)
	// 
	// In future we need to reserve space for the pre-requisites which also goes at the beginning.
	// To accomodate pre-requisites in the future, first we walk the whole list marking records
	// that can be sent in this packet and computing the space needed for these records. 
	// For TXT and SRV records, we delete the previous record if any by sending the same
	// resource record with ANY RDATA and zero rdlen. Hence, we need to have space for both of them.

	while (startRR)
		{
		AuthInfo = mDNSNULL;
		anchorRR = mDNSNULL;
		nrecords = 0;
		zoneSize = 0;
		for (rr = startRR; rr; rr = rr->next)
			{
			if (rr->SendRNow != mDNSInterfaceMark) continue;
	
			rr->SendRNow = mDNSNULL;

			if (!anchorRR)
				{
				AuthInfo = GetAuthInfoForName_internal(m, rr->zone);

				// Though we allow single record registrations for UDP to be AbsoluteMaxDNSMessageData (See
				// SendRecordRegistration) to handle large TXT records, to avoid fragmentation we limit UDP
				// message to NormalMaxDNSMessageData
				if (AuthInfo && AuthInfo->AutoTunnel) spaceleft = AbsoluteMaxDNSMessageData;
				else spaceleft = NormalMaxDNSMessageData;
		
				next = m->omsg.data;
				spaceleft -= RRAdditionalSize(m, AuthInfo);
				if (spaceleft <= 0)
					{
					LogMsg("SendGroupUpdates: ERROR!!: spaceleft is zero at the beginning");
					RRMergeFailure(m);
					return mDNSfalse;
					}
				limit = next + spaceleft;

				// Build the initial part of message before putting in the other records
 				msgid = mDNS_NewMessageID(m);
				InitializeDNSMessage(&m->omsg.h, msgid, UpdateReqFlags);
	
				// We need zone information at the beginning of the packet. Length: ZNAME, ZTYPE(2), ZCLASS(2)
				// zone has to be non-NULL for a record to be mergeable, hence it is safe to set/ examine zone
				//without checking for NULL.
				zoneSize = DomainNameLength(rr->zone) + 4;
				spaceleft -= zoneSize;
				if (spaceleft <= 0)
					{
					LogMsg("SendGroupUpdates: ERROR no space for zone information, disabling merge");
					RRMergeFailure(m);
					return mDNSfalse;
					}
				next = putZone(&m->omsg, next, limit, rr->zone, mDNSOpaque16fromIntVal(rr->resrec.rrclass));
				if (!next)
					{
					LogMsg("SendGroupUpdates: ERROR! Cannot put zone, disabling merge");
					RRMergeFailure(m);
					return mDNSfalse;
					}
				anchorRR = rr;
				}

			rrSize = RREstimatedSize(rr, zoneSize - 4);

			if ((spaceleft - rrSize) < 0) 
				{
				// If we can't fit even a single message, skip it, it will be sent separately
				// in CheckRecordUpdates
				if (!nrecords)
					{
					LogInfo("SendGroupUpdates: Skipping message %s, spaceleft %d, rrSize %d", ARDisplayString(m, rr), spaceleft, rrSize);
					// Mark this as not sent so that the caller knows about it
					rr->SendRNow = mDNSInterfaceMark;
					// We need to remove the merge delay so that we can send it immediately
					rr->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
					rr->LastAPTime = m->timenow - INIT_RECORD_REG_INTERVAL;
					rr = rr->next;
					anchorRR = mDNSNULL;
					sentallRecords = mDNSfalse;
					}
				else
					{
					LogInfo("SendGroupUpdates:1: Parsed %d records and sending using %s, spaceleft %d, rrSize %d", nrecords, ARDisplayString(m, anchorRR), spaceleft, rrSize);
					SendGroupRRMessage(m, anchorRR, next, AuthInfo);
					}
				break;		// breaks out of for loop
				}
			spaceleft -= rrSize;
			oldnext = next;
			LogInfo("SendGroupUpdates: Building a message with resource record %s, next %p, state %d", ARDisplayString(m, rr), next, rr->state);
			if (!(next = BuildUpdateMessage(m, next, rr, limit)))
				{
				// We calculated the space and if we can't fit in, we had some bug in the calculation,
				// disable merge completely.
				LogMsg("SendGroupUpdates: ptr NULL while building message with %s", ARDisplayString(m, rr));
				RRMergeFailure(m);
				return mDNSfalse;
				}
			// If our estimate was higher, adjust to the actual size
			if ((next - oldnext) > rrSize)
				LogMsg("SendGroupUpdates: ERROR!! Record size estimation is wrong for %s, Estimate %d, Actual %d, state %d", ARDisplayString(m, rr), rrSize, next - oldnext, rr->state); 
			else { spaceleft += rrSize; spaceleft -= (next - oldnext); }

			nrecords++;
			// We could have sent an update earlier with this "rr" as anchorRR for which we never got a response.
			// To preserve ordering, we blow away the previous connection before sending this.
			if (rr->tcp) { DisposeTCPConn(rr->tcp); rr->tcp = mDNSNULL;}
			rr->updateid = msgid;
	
			// By setting the retry time interval here, we will not be looking at these records
			// again when we return to CheckGroupRecordUpdates.
			SetRecordRetry(m, rr, 0);
			}
			// Either we have parsed all the records or stopped at "rr" above due to lack of space
			startRR = rr;
		}

	if (anchorRR)
		{
		LogInfo("SendGroupUpdates: Parsed %d records and sending using %s", nrecords, ARDisplayString(m, anchorRR));
		SendGroupRRMessage(m, anchorRR, next, AuthInfo);
		}
	return sentallRecords;
	}

// Merge the record registrations and send them as a group only if they
// have same DomainAuthInfo and hence the same key to put the TSIG
mDNSlocal void CheckGroupRecordUpdates(mDNS *const m)
	{
	AuthRecord *rr, *nextRR;
	// Keep sending as long as there is at least one record to be sent
	while (MarkRRForSending(m))
		{
		if (!SendGroupUpdates(m))
			{
			// if everything that was marked was not sent, send them out individually
			for (rr = m->ResourceRecords; rr; rr = nextRR)
				{
				// SendRecordRegistrtion might delete the rr from list, hence
				// dereference nextRR before calling the function
				nextRR = rr->next;
				if (rr->SendRNow == mDNSInterfaceMark)
					{
					// Any records marked for sending should be eligible to be sent out
					// immediately. Just being cautious
					if (rr->LastAPTime + rr->ThisAPInterval - m->timenow > 0)
						{ LogMsg("CheckGroupRecordUpdates: ERROR!! Resourcerecord %s not ready", ARDisplayString(m, rr)); continue; }
					rr->SendRNow = mDNSNULL;
					SendRecordRegistration(m, rr);
					}
				}
			}
		}
		
	debugf("CheckGroupRecordUpdates: No work, returning");
	return;
	}

mDNSlocal void hndlSRVChanged(mDNS *const m, AuthRecord *rr)
	{
	// Reevaluate the target always as NAT/Target could have changed while
	// we were registering/deeregistering
	domainname *dt;
	const domainname *target = GetServiceTarget(m, rr);
	if (!target || target->c[0] == 0)
		{
		// we don't have a target, if we just derregistered, then we don't have to do anything
		if (rr->state == regState_DeregPending)
			{
			LogInfo("hndlSRVChanged: SRVChanged, No Target, SRV Deregistered for %##s, state %d", rr->resrec.name->c,
				rr->state);
			rr->SRVChanged = mDNSfalse;
			dt = GetRRDomainNameTarget(&rr->resrec);
			if (dt) dt->c[0] = 0;
			rr->state = regState_NoTarget;	// Wait for the next target change
			rr->resrec.rdlength = rr->resrec.rdestimate = 0;
			return;
			}
	
		// we don't have a target, if we just registered, we need to deregister
		if (rr->state == regState_Pending)
			{
			LogInfo("hndlSRVChanged: SRVChanged, No Target, Deregistering again %##s, state %d", rr->resrec.name->c, rr->state);
			rr->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
			rr->LastAPTime = m->timenow - INIT_RECORD_REG_INTERVAL;
			rr->state = regState_DeregPending;
			return;
			}
		LogInfo("hndlSRVChanged: Not in DeregPending or RegPending state %##s, state %d", rr->resrec.name->c, rr->state);
		}
	else
		{
		// If we were in registered state and SRV changed to NULL, we deregister and come back here
		// if we have a target, we need to register again.
		//
		// if we just registered check to see if it is same. If it is different just re-register the
		// SRV and its assoicated records
		//
		// UpdateOneSRVRecord takes care of re-registering all service records
		if ((rr->state == regState_DeregPending) ||
		   (rr->state == regState_Pending && !SameDomainName(target, &rr->resrec.rdata->u.srv.target)))
			{
			dt = GetRRDomainNameTarget(&rr->resrec);
			if (dt) dt->c[0] = 0;
			rr->state = regState_NoTarget;	// NoTarget will allow us to pick up new target OR nat traversal state
			rr->resrec.rdlength = rr->resrec.rdestimate = 0;
			LogInfo("hndlSRVChanged: SRVChanged, Valid Target %##s, Registering all records for %##s, state %d",
				target->c, rr->resrec.name->c, rr->state);
			rr->SRVChanged = mDNSfalse;
			UpdateOneSRVRecord(m, rr);
			return;
			}
		// Target did not change while this record was registering. Hence, we go to
		// Registered state - the state we started from.
		if (rr->state == regState_Pending) rr->state = regState_Registered;
		}
	
	rr->SRVChanged = mDNSfalse;
	}

// Called with lock held
mDNSlocal void hndlRecordUpdateReply(mDNS *m, AuthRecord *rr, mStatus err, mDNSu32 random)
	{
	mDNSBool InvokeCallback = mDNStrue;
	mDNSIPPort UpdatePort = zeroIPPort;

	if (m->mDNS_busy != m->mDNS_reentrancy+1)
		LogMsg("hndlRecordUpdateReply: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);

	LogInfo("hndlRecordUpdateReply: err %d ID %d state %d %s(%p)", err, mDNSVal16(rr->updateid), rr->state, ARDisplayString(m, rr), rr);

	rr->updateError = err;
#if APPLE_OSX_mDNSResponder
	if (err == mStatus_BadSig) UpdateAutoTunnelDomainStatuses(m);
#endif

	SetRecordRetry(m, rr, random);

	rr->updateid = zeroID;	// Make sure that this is not considered as part of a group anymore
	// Later when need to send an update, we will get the zone data again. Thus we avoid
	// using stale information.
	//
	// Note: By clearing out the zone info here, it also helps better merging of records
	// in some cases. For example, when we get out regState_NoTarget state e.g., move out
	// of Double NAT, we want all the records to be in one update. Some BTMM records like
	// _autotunnel6 and host records are registered/deregistered when NAT state changes.
	// As they are re-registered the zone information is cleared out. To merge with other
	// records that might be possibly going out, clearing out the information here helps
	// as all of them try to get the zone data.
	if (rr->nta)
		{
		// We always expect the question to be stopped when we get a valid response from the server.
		// If the zone info tries to change during this time, updateid would be different and hence
		// this response should not have been accepted.
		if (rr->nta->question.ThisQInterval != -1)
			LogMsg("hndlRecordUpdateReply: ResourceRecord %s, zone info question %##s (%s) interval %d not -1",
				ARDisplayString(m, rr), rr->nta->question.qname.c, DNSTypeName(rr->nta->question.qtype), rr->nta->question.ThisQInterval);
		UpdatePort = rr->nta->Port;
		CancelGetZoneData(m, rr->nta);
		rr->nta = mDNSNULL;
		}

	// If we are deregistering the record, then complete the deregistration. Ignore any NAT/SRV change
	// that could have happened during that time.
	if (rr->resrec.RecordType == kDNSRecordTypeDeregistering && rr->state == regState_DeregPending)
		{
		debugf("hndlRecordUpdateReply: Received reply for deregister record %##s type %d", rr->resrec.name->c, rr->resrec.rrtype);
		if (err) LogMsg("ERROR: Deregistration of record %##s type %d failed with error %d",
						rr->resrec.name->c, rr->resrec.rrtype, err);
		rr->state = regState_Unregistered;
		CompleteDeregistration(m, rr);
		return;
		}

	// We are returning early without updating the state. When we come back from sleep we will re-register after
	// re-initializing all the state as though it is a first registration. If the record can't be registered e.g.,
	// no target, it will be deregistered. Hence, the updating to the right state should not matter when going
	// to sleep.
	if (m->SleepState)
		{
		// Need to set it to NoTarget state so that RecordReadyForSleep knows that
		// we are done
		if (rr->resrec.rrtype == kDNSType_SRV && rr->state == regState_DeregPending)
			rr->state = regState_NoTarget;
		return;
		}

	if (rr->state == regState_UpdatePending)
		{
		if (err) LogMsg("Update record failed for %##s (err %d)", rr->resrec.name->c, err);
		rr->state = regState_Registered;
		// deallocate old RData
		if (rr->UpdateCallback) rr->UpdateCallback(m, rr, rr->OrigRData, rr->OrigRDLen);
		SetNewRData(&rr->resrec, rr->InFlightRData, rr->InFlightRDLen);
		rr->OrigRData = mDNSNULL;
		rr->InFlightRData = mDNSNULL;
		}

	if (rr->SRVChanged)
		{
		if (rr->resrec.rrtype == kDNSType_SRV)
			hndlSRVChanged(m, rr);
		else
			{
			LogInfo("hndlRecordUpdateReply: Deregistered %##s (%s), state %d", rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype), rr->state);
			rr->SRVChanged = mDNSfalse; 
			if (rr->state != regState_DeregPending) LogMsg("hndlRecordUpdateReply: ResourceRecord %s not in DeregPending state %d", ARDisplayString(m, rr), rr->state);
			rr->state = regState_NoTarget;	// Wait for the next target change
			}
		return;
		}
		
	if (rr->state == regState_Pending || rr->state == regState_Refresh)
		{
		if (!err)
			{
			if (rr->state == regState_Refresh) InvokeCallback = mDNSfalse;
			rr->state = regState_Registered;
			}
		else
			{
			// Retry without lease only for non-Private domains
			LogMsg("hndlRecordUpdateReply: Registration of record %##s type %d failed with error %d", rr->resrec.name->c, rr->resrec.rrtype, err);
			if (!rr->Private && rr->uselease && err == mStatus_UnknownErr && mDNSSameIPPort(UpdatePort, UnicastDNSPort))
				{
				LogMsg("hndlRecordUpdateReply: Will retry update of record %##s without lease option", rr->resrec.name->c);
				rr->uselease = mDNSfalse;
				rr->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
				rr->LastAPTime = m->timenow - INIT_RECORD_REG_INTERVAL;
				return;
				}
			// Communicate the error to the application in the callback below
			}
		}

	if (rr->QueuedRData && rr->state == regState_Registered)
		{
		rr->state = regState_UpdatePending;
		rr->InFlightRData = rr->QueuedRData;
		rr->InFlightRDLen = rr->QueuedRDLen;
		rr->OrigRData = rr->resrec.rdata;
		rr->OrigRDLen = rr->resrec.rdlength;
		rr->QueuedRData = mDNSNULL;
		rr->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
		rr->LastAPTime = m->timenow - INIT_RECORD_REG_INTERVAL;
		return;
		}

	// Don't invoke the callback on error as this may not be useful to the client.
	// The client may potentially delete the resource record on error which we normally
	// delete during deregistration
	if (!err && InvokeCallback && rr->RecordCallback)
		{
		LogInfo("hndlRecordUpdateReply: Calling record callback on %##s", rr->resrec.name->c);
		mDNS_DropLockBeforeCallback();
		rr->RecordCallback(m, rr, err);
		mDNS_ReclaimLockAfterCallback();
		}
	// CAUTION: MUST NOT do anything more with rr after calling rr->Callback(), because the client's callback function
	// is allowed to do anything, including starting/stopping queries, registering/deregistering records, etc.
	}

mDNSexport void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID InterfaceID, mDNSu8 *pkt, mDNSu16 len)
	{
	NATTraversalInfo *ptr;
	NATAddrReply     *AddrReply    = (NATAddrReply    *)pkt;
	NATPortMapReply  *PortMapReply = (NATPortMapReply *)pkt;
	mDNSu32 nat_elapsed, our_elapsed;

	// Minimum packet is vers (1) opcode (1) err (2) upseconds (4) = 8 bytes
	if (!AddrReply->err && len < 8) { LogMsg("NAT Traversal message too short (%d bytes)", len); return; }
	if (AddrReply->vers != NATMAP_VERS) { LogMsg("Received NAT Traversal response with version %d (expected %d)", pkt[0], NATMAP_VERS); return; }

	// Read multi-byte numeric values (fields are identical in a NATPortMapReply)
	AddrReply->err       = (mDNSu16) (                                                (mDNSu16)pkt[2] << 8 | pkt[3]);
	AddrReply->upseconds = (mDNSs32) ((mDNSs32)pkt[4] << 24 | (mDNSs32)pkt[5] << 16 | (mDNSs32)pkt[6] << 8 | pkt[7]);

	nat_elapsed = AddrReply->upseconds - m->LastNATupseconds;
	our_elapsed = (m->timenow - m->LastNATReplyLocalTime) / mDNSPlatformOneSecond;
	debugf("uDNS_ReceiveNATPMPPacket %X upseconds %u nat_elapsed %d our_elapsed %d", AddrReply->opcode, AddrReply->upseconds, nat_elapsed, our_elapsed);

	// We compute a conservative estimate of how much the NAT gateways's clock should have advanced
	// 1. We subtract 12.5% from our own measured elapsed time, to allow for NAT gateways that have an inacurate clock that runs slowly
	// 2. We add a two-second safety margin to allow for rounding errors: e.g.
	//    -- if NAT gateway sends a packet at t=2.000 seconds, then one at t=7.999, that's approximately 6 real seconds,
	//       but based on the values in the packet (2,7) the apparent difference according to the packet is only 5 seconds
	//    -- if we're slow handling packets and/or we have coarse clock granularity,
	//       we could receive the t=2 packet at our t=1.999 seconds, which we round down to 1
	//       and the t=7.999 packet at our t=8.000 seconds, which we record as 8,
	//       giving an apparent local time difference of 7 seconds
	//    The two-second safety margin coves this possible calculation discrepancy
	if (AddrReply->upseconds < m->LastNATupseconds || nat_elapsed + 2 < our_elapsed - our_elapsed/8)
		{ LogMsg("NAT gateway %#a rebooted", &m->Router); RecreateNATMappings(m); }

	m->LastNATupseconds      = AddrReply->upseconds;
	m->LastNATReplyLocalTime = m->timenow;
#ifdef _LEGACY_NAT_TRAVERSAL_
	LNT_ClearState(m);
#endif // _LEGACY_NAT_TRAVERSAL_

	if (AddrReply->opcode == NATOp_AddrResponse)
		{
#if APPLE_OSX_mDNSResponder
		static char msgbuf[16];
		mDNS_snprintf(msgbuf, sizeof(msgbuf), "%d", AddrReply->err);
		mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.natpmp.AddressRequest", AddrReply->err ? "failure" : "success", msgbuf, "");
#endif
		if (!AddrReply->err && len < sizeof(NATAddrReply)) { LogMsg("NAT Traversal AddrResponse message too short (%d bytes)", len); return; }
		natTraversalHandleAddressReply(m, AddrReply->err, AddrReply->ExtAddr);
		}
	else if (AddrReply->opcode == NATOp_MapUDPResponse || AddrReply->opcode == NATOp_MapTCPResponse)
		{
		mDNSu8 Protocol = AddrReply->opcode & 0x7F;
#if APPLE_OSX_mDNSResponder
		static char msgbuf[16];
		mDNS_snprintf(msgbuf, sizeof(msgbuf), "%s - %d", AddrReply->opcode == NATOp_MapUDPResponse ? "UDP" : "TCP", PortMapReply->err);
		mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.natpmp.PortMapRequest", PortMapReply->err ? "failure" : "success", msgbuf, "");
#endif
		if (!PortMapReply->err)
			{
			if (len < sizeof(NATPortMapReply)) { LogMsg("NAT Traversal PortMapReply message too short (%d bytes)", len); return; }
			PortMapReply->NATRep_lease = (mDNSu32) ((mDNSu32)pkt[12] << 24 | (mDNSu32)pkt[13] << 16 | (mDNSu32)pkt[14] << 8 | pkt[15]);
			}

		// Since some NAT-PMP server implementations don't return the requested internal port in
		// the reply, we can't associate this reply with a particular NATTraversalInfo structure.
		// We globally keep track of the most recent error code for mappings.
		m->LastNATMapResultCode = PortMapReply->err;
		
		for (ptr = m->NATTraversals; ptr; ptr=ptr->next)
			if (ptr->Protocol == Protocol && mDNSSameIPPort(ptr->IntPort, PortMapReply->intport))
				natTraversalHandlePortMapReply(m, ptr, InterfaceID, PortMapReply->err, PortMapReply->extport, PortMapReply->NATRep_lease);
		}
	else { LogMsg("Received NAT Traversal response with version unknown opcode 0x%X", AddrReply->opcode); return; }

	// Don't need an SSDP socket if we get a NAT-PMP packet
	if (m->SSDPSocket) { debugf("uDNS_ReceiveNATPMPPacket destroying SSDPSocket %p", &m->SSDPSocket); mDNSPlatformUDPClose(m->SSDPSocket); m->SSDPSocket = mDNSNULL; }
	}

// <rdar://problem/3925163> Shorten DNS-SD queries to avoid NAT bugs
// <rdar://problem/4288449> Add check to avoid crashing NAT gateways that have buggy DNS relay code
//
// We know of bugs in home NAT gateways that cause them to crash if they receive certain DNS queries.
// The DNS queries that make them crash are perfectly legal DNS queries, but even if they weren't,
// the gateway shouldn't crash -- in today's world of viruses and network attacks, software has to
// be written assuming that a malicious attacker could send them any packet, properly-formed or not.
// Still, we don't want to be crashing people's home gateways, so we go out of our way to avoid
// the queries that crash them.
//
// Some examples:
//
// 1. Any query where the name ends in ".in-addr.arpa." and the text before this is 32 or more bytes.
//    The query type does not need to be PTR -- the gateway will crash for any query type.
//    e.g. "ping long-name-crashes-the-buggy-router.in-addr.arpa" will crash one of these.
//
// 2. Any query that results in a large response with the TC bit set.
//
// 3. Any PTR query that doesn't begin with four decimal numbers.
//    These gateways appear to assume that the only possible PTR query is a reverse-mapping query
//    (e.g. "1.0.168.192.in-addr.arpa") and if they ever get a PTR query where the first four
//    labels are not all decimal numbers in the range 0-255, they handle that by crashing.
//    These gateways also ignore the remainder of the name following the four decimal numbers
//    -- whether or not it actually says in-addr.arpa, they just make up an answer anyway.
//
// The challenge therefore is to craft a query that will discern whether the DNS server
// is one of these buggy ones, without crashing it. Furthermore we don't want our test
// queries making it all the way to the root name servers, putting extra load on those
// name servers and giving Apple a bad reputation. To this end we send this query:
//     dig -t ptr 1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
//
// The text preceding the ".in-addr.arpa." is under 32 bytes, so it won't cause crash (1).
// It will not yield a large response with the TC bit set, so it won't cause crash (2).
// It starts with four decimal numbers, so it won't cause crash (3).
// The name falls within the "1.0.0.127.in-addr.arpa." domain, the reverse-mapping name for the local
// loopback address, and therefore the query will black-hole at the first properly-configured DNS server
// it reaches, making it highly unlikely that this query will make it all the way to the root.
//
// Finally, the correct response to this query is NXDOMAIN or a similar error, but the
// gateways that ignore the remainder of the name following the four decimal numbers
// give themselves away by actually returning a result for this nonsense query.

mDNSlocal const domainname *DNSRelayTestQuestion = (const domainname*)
	"\x1" "1" "\x1" "0" "\x1" "0" "\x3" "127" "\xa" "dnsbugtest"
	"\x1" "1" "\x1" "0" "\x1" "0" "\x3" "127" "\x7" "in-addr" "\x4" "arpa";

// See comments above for DNSRelayTestQuestion
// If this is the kind of query that has the risk of crashing buggy DNS servers, we do a test question first
mDNSlocal mDNSBool NoTestQuery(DNSQuestion *q)
	{
	int i;
	mDNSu8 *p = q->qname.c;
	if (q->AuthInfo) return(mDNStrue);		// Don't need a test query for private queries sent directly to authoritative server over TLS/TCP
	if (q->qtype != kDNSType_PTR) return(mDNStrue);		// Don't need a test query for any non-PTR queries
	for (i=0; i<4; i++)		// If qname does not begin with num.num.num.num, can't skip the test query
		{
		if (p[0] < 1 || p[0] > 3) return(mDNSfalse);
		if (              p[1] < '0' || p[1] > '9' ) return(mDNSfalse);
		if (p[0] >= 2 && (p[2] < '0' || p[2] > '9')) return(mDNSfalse);
		if (p[0] >= 3 && (p[3] < '0' || p[3] > '9')) return(mDNSfalse);
		p += 1 + p[0];
		}
	// If remainder of qname is ".in-addr.arpa.", this is a vanilla reverse-mapping query and
	// we can safely do it without needing a test query first, otherwise we need the test query.
	return(SameDomainName((domainname*)p, (const domainname*)"\x7" "in-addr" "\x4" "arpa"));
	}

// Returns mDNStrue if response was handled
mDNSlocal mDNSBool uDNS_ReceiveTestQuestionResponse(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
	const mDNSAddr *const srcaddr, const mDNSIPPort srcport)
	{
	const mDNSu8 *ptr = msg->data;
	DNSQuestion pktq;
	DNSServer *s;
	mDNSu32 result = 0;

	// 1. Find out if this is an answer to one of our test questions
	if (msg->h.numQuestions != 1) return(mDNSfalse);
	ptr = getQuestion(msg, ptr, end, mDNSInterface_Any, &pktq);
	if (!ptr) return(mDNSfalse);
	if (pktq.qtype != kDNSType_PTR || pktq.qclass != kDNSClass_IN) return(mDNSfalse);
	if (!SameDomainName(&pktq.qname, DNSRelayTestQuestion)) return(mDNSfalse);

	// 2. If the DNS relay gave us a positive response, then it's got buggy firmware
	// else, if the DNS relay gave us an error or no-answer response, it passed our test
	if ((msg->h.flags.b[1] & kDNSFlag1_RC_Mask) == kDNSFlag1_RC_NoErr && msg->h.numAnswers > 0)
		result = DNSServer_Failed;
	else
		result = DNSServer_Passed;

	// 3. Find occurrences of this server in our list, and mark them appropriately
	for (s = m->DNSServers; s; s = s->next)
		{
		mDNSBool matchaddr = (s->teststate != result && mDNSSameAddress(srcaddr, &s->addr) && mDNSSameIPPort(srcport, s->port));
		mDNSBool matchid   = (s->teststate == DNSServer_Untested && mDNSSameOpaque16(msg->h.id, s->testid));
		if (matchaddr || matchid)
			{
			DNSQuestion *q;
			s->teststate = result;
			if (result == DNSServer_Passed)
				{
				LogInfo("DNS Server %#a:%d (%#a:%d) %d passed%s",
					&s->addr, mDNSVal16(s->port), srcaddr, mDNSVal16(srcport), mDNSVal16(s->testid),
					matchaddr ? "" : " NOTE: Reply did not come from address to which query was sent");
				}
			else
				{
				LogMsg("NOTE: Wide-Area Service Discovery disabled to avoid crashing defective DNS relay %#a:%d (%#a:%d) %d%s",
					&s->addr, mDNSVal16(s->port), srcaddr, mDNSVal16(srcport), mDNSVal16(s->testid),
					matchaddr ? "" : " NOTE: Reply did not come from address to which query was sent");
				}

			// If this server has just changed state from DNSServer_Untested to DNSServer_Passed, then retrigger any waiting questions.
			// We use the NoTestQuery() test so that we only retrigger questions that were actually blocked waiting for this test to complete.
			if (result == DNSServer_Passed)		// Unblock any questions that were waiting for this result
				for (q = m->Questions; q; q=q->next)
					if (q->qDNSServer == s && !NoTestQuery(q))
						{
						q->ThisQInterval = INIT_UCAST_POLL_INTERVAL / QuestionIntervalStep;
						q->unansweredQueries = 0;
						q->LastQTime = m->timenow - q->ThisQInterval;
						m->NextScheduledQuery = m->timenow;
						}
			}
		}

	return(mDNStrue); // Return mDNStrue to tell uDNS_ReceiveMsg it doesn't need to process this packet further
	}

// Called from mDNSCoreReceive with the lock held
mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr, const mDNSIPPort srcport)
	{
	DNSQuestion *qptr;
	mStatus err = mStatus_NoError;

	mDNSu8 StdR    = kDNSFlag0_QR_Response | kDNSFlag0_OP_StdQuery;
	mDNSu8 UpdateR = kDNSFlag0_QR_Response | kDNSFlag0_OP_Update;
	mDNSu8 QR_OP   = (mDNSu8)(msg->h.flags.b[0] & kDNSFlag0_QROP_Mask);
	mDNSu8 rcode   = (mDNSu8)(msg->h.flags.b[1] & kDNSFlag1_RC_Mask);

	(void)srcport; // Unused

	debugf("uDNS_ReceiveMsg from %#-15a with "
		"%2d Question%s %2d Answer%s %2d Authorit%s %2d Additional%s %d bytes",
		srcaddr,
		msg->h.numQuestions,   msg->h.numQuestions   == 1 ? ", "   : "s,",
		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 (QR_OP == StdR)
		{
		//if (srcaddr && recvLLQResponse(m, msg, end, srcaddr, srcport)) return;
		if (uDNS_ReceiveTestQuestionResponse(m, msg, end, srcaddr, srcport)) return;
		for (qptr = m->Questions; qptr; qptr = qptr->next)
			if (msg->h.flags.b[0] & kDNSFlag0_TC && mDNSSameOpaque16(qptr->TargetQID, msg->h.id) && m->timenow - qptr->LastQTime < RESPONSE_WINDOW)
				{
				if (!srcaddr) LogMsg("uDNS_ReceiveMsg: TCP DNS response had TC bit set: ignoring");
				else
					{
					// Don't reuse TCP connections. We might have failed over to a different DNS server
					// while the first TCP connection is in progress. We need a new TCP connection to the
					// new DNS server. So, always try to establish a new connection.
					if (qptr->tcp) { DisposeTCPConn(qptr->tcp); qptr->tcp = mDNSNULL; }
					qptr->tcp = MakeTCPConn(m, mDNSNULL, mDNSNULL, kTCPSocketFlags_Zero, srcaddr, srcport, mDNSNULL, qptr, mDNSNULL);
					}
				}
		}

	if (QR_OP == UpdateR)
		{
		mDNSu32 lease = GetPktLease(m, msg, end);
		mDNSs32 expire = m->timenow + (mDNSs32)lease * mDNSPlatformOneSecond;
		mDNSu32 random = mDNSRandom((mDNSs32)lease * mDNSPlatformOneSecond/10);

		//rcode = kDNSFlag1_RC_ServFail;	// Simulate server failure (rcode 2)

		// Walk through all the records that matches the messageID. There could be multiple
		// records if we had sent them in a group
		if (m->CurrentRecord)
			LogMsg("uDNS_ReceiveMsg ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
		m->CurrentRecord = m->ResourceRecords;
		while (m->CurrentRecord)
			{
			AuthRecord *rptr = m->CurrentRecord;
			m->CurrentRecord = m->CurrentRecord->next;
			if (AuthRecord_uDNS(rptr) && mDNSSameOpaque16(rptr->updateid, msg->h.id))
				{
				err = checkUpdateResult(m, rptr->resrec.name, rcode, msg, end);
				if (!err && rptr->uselease && lease)
					if (rptr->expire - expire >= 0 || rptr->state != regState_UpdatePending)
						{
						rptr->expire = expire;
						rptr->refreshCount = 0;
						}
				// We pass the random value to make sure that if we update multiple
				// records, they all get the same random value
				hndlRecordUpdateReply(m, rptr, err, random);
				}
			}
		}
	debugf("Received unexpected response: ID %d matches no active records", mDNSVal16(msg->h.id));
	}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - Query Routines
#endif

mDNSexport void sendLLQRefresh(mDNS *m, DNSQuestion *q)
	{
	mDNSu8 *end;
	LLQOptData llq;
	mDNSu8 *limit = m->omsg.data + AbsoluteMaxDNSMessageData;

	if (q->ReqLease)
		if ((q->state == LLQ_Established && q->ntries >= kLLQ_MAX_TRIES) || q->expire - m->timenow < 0)
			{
			LogMsg("Unable to refresh LLQ %##s (%s) - will retry in %d seconds", q->qname.c, DNSTypeName(q->qtype), LLQ_POLL_INTERVAL / mDNSPlatformOneSecond);
			StartLLQPolling(m,q);
			return;
			}

	llq.vers     = kLLQ_Vers;
	llq.llqOp    = kLLQOp_Refresh;
	llq.err      = q->tcp ? GetLLQEventPort(m, &q->servAddr) : LLQErr_NoError;	// If using TCP tell server what UDP port to send notifications to
	llq.id       = q->id;
	llq.llqlease = q->ReqLease;

	InitializeDNSMessage(&m->omsg.h, q->TargetQID, uQueryFlags);
	end = putLLQ(&m->omsg, m->omsg.data, q, &llq);
	if (!end) { LogMsg("sendLLQRefresh: putLLQ failed %##s (%s)", q->qname.c, DNSTypeName(q->qtype)); return; }

	// Note that we (conditionally) add HINFO and TSIG here, since the question might be going away,
	// so we may not be able to reference it (most importantly it's AuthInfo) when we actually send the message
	end = putHINFO(m, &m->omsg, end, q->AuthInfo, limit);
	if (!end) { LogMsg("sendLLQRefresh: putHINFO failed %##s (%s)", q->qname.c, DNSTypeName(q->qtype)); return; }

	if (PrivateQuery(q))
		{
		DNSDigest_SignMessageHostByteOrder(&m->omsg, &end, q->AuthInfo);
		if (!end) { LogMsg("sendLLQRefresh: DNSDigest_SignMessage failed %##s (%s)", q->qname.c, DNSTypeName(q->qtype)); return; }
		}

	if (PrivateQuery(q) && !q->tcp)
		{
		LogInfo("sendLLQRefresh setting up new TLS session %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
		if (!q->nta) { LogMsg("sendLLQRefresh:ERROR!! q->nta is NULL for %##s (%s)", q->qname.c, DNSTypeName(q->qtype)); return; }
		q->tcp = MakeTCPConn(m, &m->omsg, end, kTCPSocketFlags_UseTLS, &q->servAddr, q->servPort, &q->nta->Host, q, mDNSNULL);
		}
	else
		{
		mStatus err;

		// if AuthInfo and AuthInfo->AutoTunnel is set, we use the TCP socket but don't need to pass the AuthInfo as
		// we already protected the message above.
		LogInfo("sendLLQRefresh: using existing %s session %##s (%s)", PrivateQuery(q) ? "TLS" : "UDP",
			q->qname.c, DNSTypeName(q->qtype));

		err = mDNSSendDNSMessage(m, &m->omsg, end, mDNSInterface_Any, q->LocalSocket, &q->servAddr, q->servPort, q->tcp ? q->tcp->sock : mDNSNULL, mDNSNULL);
		if (err)
			{
			LogMsg("sendLLQRefresh: mDNSSendDNSMessage%s failed: %d", q->tcp ? " (TCP)" : "", err);
			if (q->tcp) { DisposeTCPConn(q->tcp); q->tcp = mDNSNULL; }
			}
		}

	q->ntries++;

	debugf("sendLLQRefresh ntries %d %##s (%s)", q->ntries, q->qname.c, DNSTypeName(q->qtype));

	q->LastQTime = m->timenow;
	SetNextQueryTime(m, q);
	}

mDNSexport void LLQGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo)
	{
	DNSQuestion *q = (DNSQuestion *)zoneInfo->ZoneDataContext;

	mDNS_Lock(m);

	// If we get here it means that the GetZoneData operation has completed.
	// We hold on to the zone data if it is AutoTunnel as we use the hostname
	// in zoneInfo during the TLS connection setup.
	q->servAddr = zeroAddr;
	q->servPort = zeroIPPort;

	if (!err && zoneInfo && !mDNSIPPortIsZero(zoneInfo->Port) && !mDNSAddressIsZero(&zoneInfo->Addr) && zoneInfo->Host.c[0])
		{
		q->servAddr = zoneInfo->Addr;
		q->servPort = zoneInfo->Port;
		if (!PrivateQuery(q))
			{
			// We don't need the zone data as we use it only for the Host information which we
			// don't need if we are not going to use TLS connections.
			if (q->nta)
				{
				if (q->nta != zoneInfo) LogMsg("LLQGotZoneData: nta (%p) != zoneInfo (%p)  %##s (%s)", q->nta, zoneInfo, q->qname.c, DNSTypeName(q->qtype));
				CancelGetZoneData(m, q->nta);
				q->nta = mDNSNULL;
				}
			}
		q->ntries = 0;
		debugf("LLQGotZoneData %#a:%d", &q->servAddr, mDNSVal16(q->servPort));
		startLLQHandshake(m, q);
		}
	else
		{
		if (q->nta)
			{
			if (q->nta != zoneInfo) LogMsg("LLQGotZoneData: nta (%p) != zoneInfo (%p)  %##s (%s)", q->nta, zoneInfo, q->qname.c, DNSTypeName(q->qtype));
			CancelGetZoneData(m, q->nta);
			q->nta = mDNSNULL;
			}
		StartLLQPolling(m,q);
		if (err == mStatus_NoSuchNameErr) 
			{
			// this actually failed, so mark it by setting address to all ones 
			q->servAddr.type = mDNSAddrType_IPv4; 
			q->servAddr.ip.v4 = onesIPv4Addr; 
			}
		}

	mDNS_Unlock(m);
	}

// Called in normal callback context (i.e. mDNS_busy and mDNS_reentrancy are both 1)
mDNSlocal void PrivateQueryGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo)
	{
	DNSQuestion *q = (DNSQuestion *) zoneInfo->ZoneDataContext;

	LogInfo("PrivateQueryGotZoneData %##s (%s) err %d Zone %##s Private %d", q->qname.c, DNSTypeName(q->qtype), err, zoneInfo->ZoneName.c, zoneInfo->ZonePrivate);

	if (q->nta != zoneInfo) LogMsg("PrivateQueryGotZoneData:ERROR!!: nta (%p) != zoneInfo (%p)  %##s (%s)", q->nta, zoneInfo, q->qname.c, DNSTypeName(q->qtype));

	if (err || !zoneInfo || mDNSAddressIsZero(&zoneInfo->Addr) || mDNSIPPortIsZero(zoneInfo->Port) || !zoneInfo->Host.c[0])
		{
		LogInfo("PrivateQueryGotZoneData: ERROR!! %##s (%s) invoked with error code %d %p %#a:%d",
			q->qname.c, DNSTypeName(q->qtype), err, zoneInfo,
			zoneInfo ? &zoneInfo->Addr : mDNSNULL,
			zoneInfo ? mDNSVal16(zoneInfo->Port) : 0);
		CancelGetZoneData(m, q->nta);
		q->nta = mDNSNULL;
		return;
		}

	if (!zoneInfo->ZonePrivate)
		{
		debugf("Private port lookup failed -- retrying without TLS -- %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
		q->AuthInfo      = mDNSNULL;		// Clear AuthInfo so we try again non-private
		q->ThisQInterval = InitialQuestionInterval;
		q->LastQTime     = m->timenow - q->ThisQInterval;
		CancelGetZoneData(m, q->nta);
		q->nta = mDNSNULL;
		mDNS_Lock(m);
		SetNextQueryTime(m, q);
		mDNS_Unlock(m);
		return;
		// Next call to uDNS_CheckCurrentQuestion() will do this as a non-private query
		}

	if (!PrivateQuery(q))
		{
		LogMsg("PrivateQueryGotZoneData: ERROR!! Not a private query %##s (%s) AuthInfo %p", q->qname.c, DNSTypeName(q->qtype), q->AuthInfo);
		CancelGetZoneData(m, q->nta);
		q->nta = mDNSNULL;
		return;
		}

	q->TargetQID = mDNS_NewMessageID(m);
	if (q->tcp) { DisposeTCPConn(q->tcp); q->tcp = mDNSNULL; }
	if (!q->nta) { LogMsg("PrivateQueryGotZoneData:ERROR!! nta is NULL for %##s (%s)", q->qname.c, DNSTypeName(q->qtype)); return; }
	q->tcp = MakeTCPConn(m, mDNSNULL, mDNSNULL, kTCPSocketFlags_UseTLS, &zoneInfo->Addr, zoneInfo->Port, &q->nta->Host, q, mDNSNULL);
	if (q->nta) { CancelGetZoneData(m, q->nta); q->nta = mDNSNULL; }
	}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - Dynamic Updates
#endif

// 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 *ptr;
	int c1, c2;

	if (newRR->nta != zoneData)
		LogMsg("RecordRegistrationGotZoneData: nta (%p) != zoneData (%p)  %##s (%s)", newRR->nta, zoneData, newRR->resrec.name->c, DNSTypeName(newRR->resrec.rrtype));

	if (m->mDNS_busy != m->mDNS_reentrancy)
		LogMsg("RecordRegistrationGotZoneData: mDNS_busy (%ld) != mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);

	// make sure record is still in list (!!!)
	for (ptr = m->ResourceRecords; ptr; ptr = ptr->next) if (ptr == newRR) break;
	if (!ptr)
		{
		LogMsg("RecordRegistrationGotZoneData - RR no longer in list.  Discarding.");
		CancelGetZoneData(m, newRR->nta);
		newRR->nta = mDNSNULL;
		return;
		}

	// check error/result
	if (err)
		{
		if (err != mStatus_NoSuchNameErr) LogMsg("RecordRegistrationGotZoneData: error %d", err);
		CancelGetZoneData(m, newRR->nta);
		newRR->nta = mDNSNULL;
		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);
		CancelGetZoneData(m, newRR->nta);
		newRR->nta = mDNSNULL;
		return;
		}

	// Don't try to do updates to the root name server.
	// We might be tempted also to block updates to any single-label name server (e.g. com, edu, net, etc.) but some
	// organizations use their own private pseudo-TLD, like ".home", etc, and we don't want to block that.
	if (zoneData->ZoneName.c[0] == 0)
		{
		LogInfo("RecordRegistrationGotZoneData: No name server found claiming responsibility for \"%##s\"!", newRR->resrec.name->c);
		CancelGetZoneData(m, newRR->nta);
		newRR->nta = mDNSNULL;
		return;
		}

	// Store discovered zone data
	c1 = CountLabels(newRR->resrec.name);
	c2 = CountLabels(&zoneData->ZoneName);
	if (c2 > c1)
		{
		LogMsg("RecordRegistrationGotZoneData: Zone \"%##s\" is longer than \"%##s\"", zoneData->ZoneName.c, newRR->resrec.name->c);
		CancelGetZoneData(m, newRR->nta);
		newRR->nta = mDNSNULL;
		return;
		}
	newRR->zone = SkipLeadingLabels(newRR->resrec.name, c1-c2);
	if (!SameDomainName(newRR->zone, &zoneData->ZoneName))
		{
		LogMsg("RecordRegistrationGotZoneData: Zone \"%##s\" does not match \"%##s\" for \"%##s\"", newRR->zone->c, zoneData->ZoneName.c, newRR->resrec.name->c);
		CancelGetZoneData(m, newRR->nta);
		newRR->nta = mDNSNULL;
		return;
		}

	if (mDNSIPPortIsZero(zoneData->Port) || mDNSAddressIsZero(&zoneData->Addr) || !zoneData->Host.c[0])
		{
		LogInfo("RecordRegistrationGotZoneData: No _dns-update._udp service found for \"%##s\"!", newRR->resrec.name->c);
		CancelGetZoneData(m, newRR->nta);
		newRR->nta = mDNSNULL;
		return;
		}

	newRR->Private      = zoneData->ZonePrivate;
	debugf("RecordRegistrationGotZoneData: Set zone information for %##s %##s to %#a:%d",
		newRR->resrec.name->c, zoneData->ZoneName.c, &zoneData->Addr, mDNSVal16(zoneData->Port));

	// If we are deregistering, uDNS_DeregisterRecord will do that as it has the zone data now.
	if (newRR->state == regState_DeregPending)
		{
		mDNS_Lock(m);
		uDNS_DeregisterRecord(m, newRR);
		mDNS_Unlock(m);
		return;
		}

	if (newRR->resrec.rrtype == kDNSType_SRV)
		{
		const domainname *target;
		// Reevaluate the target always as NAT/Target could have changed while
		// we were fetching zone data.
		mDNS_Lock(m);
		target = GetServiceTarget(m, newRR);
		mDNS_Unlock(m);
		if (!target || target->c[0] == 0)
			{
			domainname *t = GetRRDomainNameTarget(&newRR->resrec);
			LogInfo("RecordRegistrationGotZoneData - no target for %##s", newRR->resrec.name->c);
			if (t) t->c[0] = 0;
			newRR->resrec.rdlength = newRR->resrec.rdestimate = 0;
			newRR->state = regState_NoTarget;
			CancelGetZoneData(m, newRR->nta);
			newRR->nta = mDNSNULL;
			return;
			}
		}
	// If we have non-zero service port (always?)
	// and a private address, and update server is non-private
	// and this service is AutoTarget
	// then initiate a NAT mapping request. On completion it will do SendRecordRegistration() for us
	if (newRR->resrec.rrtype == kDNSType_SRV && !mDNSIPPortIsZero(newRR->resrec.rdata->u.srv.port) &&
		mDNSv4AddrIsRFC1918(&m->AdvertisedV4.ip.v4) && newRR->nta && !mDNSAddrIsRFC1918(&newRR->nta->Addr) &&
		newRR->AutoTarget == Target_AutoHostAndNATMAP)
		{
		DomainAuthInfo *AuthInfo;
		AuthInfo = GetAuthInfoForName(m, newRR->resrec.name);
		if (AuthInfo && AuthInfo->AutoTunnel)
			{
			domainname *t = GetRRDomainNameTarget(&newRR->resrec);
			LogMsg("RecordRegistrationGotZoneData: ERROR!! AutoTunnel has Target_AutoHostAndNATMAP for %s", ARDisplayString(m, newRR));
			if (t) t->c[0] = 0;
			newRR->resrec.rdlength = newRR->resrec.rdestimate = 0;
			newRR->state = regState_NoTarget;
			CancelGetZoneData(m, newRR->nta);
			newRR->nta = mDNSNULL;
			return;
			}
		// During network transitions, we are called multiple times in different states. Setup NAT
		// state just once for this record.
		if (!newRR->NATinfo.clientContext)
			{
			LogInfo("RecordRegistrationGotZoneData StartRecordNatMap %s", ARDisplayString(m, newRR));
			newRR->state = regState_NATMap;
			StartRecordNatMap(m, newRR);
			return;
			}
		else LogInfo("RecordRegistrationGotZoneData: StartRecordNatMap for %s, state %d, context %p", ARDisplayString(m, newRR), newRR->state, newRR->NATinfo.clientContext);
		}
	mDNS_Lock(m);
	// We want IsRecordMergeable to check whether it is a record whose update can be
	// sent with others. We set the time before we call IsRecordMergeable, so that
	// it does not fail this record based on time. We are interested in other checks
	// at this time. If a previous update resulted in error, then don't reset the
	// interval. Preserve the back-off so that we don't keep retrying aggressively.
	if (newRR->updateError == mStatus_NoError)
		{
		newRR->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
		newRR->LastAPTime = m->timenow - INIT_RECORD_REG_INTERVAL;
		}
	if (IsRecordMergeable(m, newRR, m->timenow + MERGE_DELAY_TIME))
		{
		// Delay the record registration by MERGE_DELAY_TIME so that we can merge them
		// into one update
		LogInfo("RecordRegistrationGotZoneData: Delayed registration for %s", ARDisplayString(m, newRR));
		newRR->LastAPTime += MERGE_DELAY_TIME;
		}
	mDNS_Unlock(m);
	}

mDNSlocal void SendRecordDeregistration(mDNS *m, AuthRecord *rr)
	{
	mDNSu8 *ptr = m->omsg.data;
	mDNSu8 *limit;
	DomainAuthInfo *AuthInfo;

	if (m->mDNS_busy != m->mDNS_reentrancy+1)
		LogMsg("SendRecordDeRegistration: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);

	if (!rr->nta || mDNSIPv4AddressIsZero(rr->nta->Addr.ip.v4))
		{
		LogMsg("SendRecordDeRegistration: No zone info for Resource record %s RecordType %d", ARDisplayString(m, rr), rr->resrec.RecordType);
		return;
		}

	limit = ptr + AbsoluteMaxDNSMessageData;
	AuthInfo = GetAuthInfoForName_internal(m, rr->resrec.name);
	limit -= RRAdditionalSize(m, AuthInfo);

	rr->updateid = mDNS_NewMessageID(m);
	InitializeDNSMessage(&m->omsg.h, rr->updateid, UpdateReqFlags);

	// set zone
	ptr = putZone(&m->omsg, ptr, limit, rr->zone, mDNSOpaque16fromIntVal(rr->resrec.rrclass));
	if (!ptr) goto exit;

	ptr = BuildUpdateMessage(m, ptr, rr, limit);

	if (!ptr) goto exit;

	if (rr->Private)
		{
		LogInfo("SendRecordDeregistration TCP %p %s", rr->tcp, ARDisplayString(m, rr));
		if (rr->tcp) LogInfo("SendRecordDeregistration: Disposing existing TCP connection for %s", ARDisplayString(m, rr));
		if (rr->tcp) { DisposeTCPConn(rr->tcp); rr->tcp = mDNSNULL; }
		if (!rr->nta) { LogMsg("SendRecordDeregistration:Private:ERROR!! nta is NULL for %s", ARDisplayString(m, rr)); return; }
		rr->tcp = MakeTCPConn(m, &m->omsg, ptr, kTCPSocketFlags_UseTLS, &rr->nta->Addr, rr->nta->Port, &rr->nta->Host, mDNSNULL, rr);
		}
	else
		{
		mStatus err;
		LogInfo("SendRecordDeregistration UDP %s", ARDisplayString(m, rr));
		if (!rr->nta) { LogMsg("SendRecordDeregistration:ERROR!! nta is NULL for %s", ARDisplayString(m, rr)); return; }
		err = mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, mDNSNULL, &rr->nta->Addr, rr->nta->Port, mDNSNULL, GetAuthInfoForName_internal(m, rr->resrec.name));
		if (err) debugf("ERROR: SendRecordDeregistration - mDNSSendDNSMessage - %d", err);
		//if (rr->state == regState_DeregPending) CompleteDeregistration(m, rr);		// Don't touch rr after this
		}
	SetRecordRetry(m, rr, 0);
	return;
exit:
	LogMsg("SendRecordDeregistration: Error formatting message for %s", ARDisplayString(m, rr));
	}

mDNSexport mStatus uDNS_DeregisterRecord(mDNS *const m, AuthRecord *const rr)
	{
	DomainAuthInfo *info;

	LogInfo("uDNS_DeregisterRecord: Resource Record %s, state %d", ARDisplayString(m, rr), rr->state);

	switch (rr->state)
		{
		case regState_Refresh:
		case regState_Pending:
		case regState_UpdatePending:
		case regState_Registered: break;
		case regState_DeregPending: break;

		case regState_NATError: 
		case regState_NATMap:
		// A record could be in NoTarget to start with if the corresponding SRV record could not find a target.
		// It is also possible to reenter the NoTarget state when we move to a network with a NAT that has
		// no NAT-PMP/UPnP support. In that case before we entered NoTarget, we already deregistered with
		// the server.
		case regState_NoTarget: 
		case regState_Unregistered:
		case regState_Zero:
		default:
			LogInfo("uDNS_DeregisterRecord: State %d for %##s type %s", rr->state, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
			// This function may be called during sleep when there are no sleep proxy servers
			if (rr->resrec.RecordType == kDNSRecordTypeDeregistering) CompleteDeregistration(m, rr);
			return mStatus_NoError;
		}

	// If a current group registration is pending, we can't send this deregisration till that registration
	// has reached the server i.e., the ordering is important. Previously, if we did not send this
	// registration in a group, then the previous connection will be torn down as part of sending the
	// deregistration. If we send this in a group, we need to locate the resource record that was used
	// to send this registration and terminate that connection. This means all the updates on that might
	// be lost (assuming the response is not waiting for us at the socket) and the retry will send the
	// update again sometime in the near future.
	//
	// NOTE: SSL handshake failures normally free the TCP connection immediately. Hence, you may not
	// find the TCP below there. This case can happen only when tcp is trying to actively retransmit
	// the request or SSL negotiation taking time i.e resource record is actively trying to get the
	// message to the server. During that time a deregister has to happen.

	if (!mDNSOpaque16IsZero(rr->updateid))
		{
		AuthRecord *anchorRR;
		mDNSBool found = mDNSfalse;
		for (anchorRR = m->ResourceRecords; anchorRR; anchorRR = anchorRR->next)
			{
			if (AuthRecord_uDNS(rr) && mDNSSameOpaque16(anchorRR->updateid, rr->updateid) && anchorRR->tcp)
				{
				LogInfo("uDNS_DeregisterRecord: Found Anchor RR %s terminated", ARDisplayString(m, anchorRR));
				if (found)
					LogMsg("uDNS_DeregisterRecord: ERROR: Another anchorRR %s found", ARDisplayString(m, anchorRR));
				DisposeTCPConn(anchorRR->tcp);
				anchorRR->tcp = mDNSNULL;
				found = mDNStrue;
				}
			}
		if (!found) LogInfo("uDNSDeregisterRecord: Cannot find the anchor Resource Record for %s, not an error", ARDisplayString(m, rr));
		}

	// Retry logic for deregistration should be no different from sending registration the first time.
	// Currently ThisAPInterval most likely is set to the refresh interval
	rr->state          = regState_DeregPending;
	rr->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
	rr->LastAPTime     = m->timenow - INIT_RECORD_REG_INTERVAL;
	info = GetAuthInfoForName_internal(m, rr->resrec.name);
	if (IsRecordMergeable(m, rr, m->timenow + MERGE_DELAY_TIME))
		{
		// Delay the record deregistration by MERGE_DELAY_TIME so that we can merge them
		// into one update. If the domain is being deleted, delay by 2 * MERGE_DELAY_TIME
		// so that we can merge all the AutoTunnel records and the service records in
		// one update (they get deregistered a little apart)
		if (info && info->deltime) rr->LastAPTime += (2 * MERGE_DELAY_TIME);
		else rr->LastAPTime += MERGE_DELAY_TIME;
		}
	// IsRecordMergeable could have returned false for several reasons e.g., DontMerge is set or
	// no zone information. Most likely it is the latter, CheckRecordUpdates will fetch the zone
	// data when it encounters this record.

	if (m->NextuDNSEvent - (rr->LastAPTime + rr->ThisAPInterval) >= 0)
		m->NextuDNSEvent = (rr->LastAPTime + rr->ThisAPInterval);

	return mStatus_NoError;
	}

mDNSexport mStatus uDNS_UpdateRecord(mDNS *m, AuthRecord *rr)
	{
	LogInfo("uDNS_UpdateRecord: Resource Record %##s, state %d", rr->resrec.name->c, rr->state);
	switch(rr->state)
		{
		case regState_DeregPending:
		case regState_Unregistered:
			// not actively registered
			goto unreg_error;

		case regState_NATMap:
		case regState_NoTarget:
			// change rdata directly since it hasn't been sent yet
			if (rr->UpdateCallback) rr->UpdateCallback(m, rr, rr->resrec.rdata, rr->resrec.rdlength);
			SetNewRData(&rr->resrec, rr->NewRData, rr->newrdlength);
			rr->NewRData = mDNSNULL;
			return mStatus_NoError;

		case regState_Pending:
		case regState_Refresh:
		case regState_UpdatePending:
			// registration in-flight. queue rdata and return
			if (rr->QueuedRData && rr->UpdateCallback)
				// if unsent rdata is already queued, free it before we replace it
				rr->UpdateCallback(m, rr, rr->QueuedRData, rr->QueuedRDLen);
			rr->QueuedRData = rr->NewRData;
			rr->QueuedRDLen = rr->newrdlength;
			rr->NewRData = mDNSNULL;
			return mStatus_NoError;

		case regState_Registered:
			rr->OrigRData = rr->resrec.rdata;
			rr->OrigRDLen = rr->resrec.rdlength;
			rr->InFlightRData = rr->NewRData;
			rr->InFlightRDLen = rr->newrdlength;
			rr->NewRData = mDNSNULL;
			rr->state = regState_UpdatePending;
			rr->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
			rr->LastAPTime = m->timenow - INIT_RECORD_REG_INTERVAL;
			return mStatus_NoError;

		case regState_NATError:
			LogMsg("ERROR: uDNS_UpdateRecord called for record %##s with bad state regState_NATError", rr->resrec.name->c);
			return mStatus_UnknownErr;	// states for service records only

		default: LogMsg("uDNS_UpdateRecord: Unknown state %d for %##s", rr->state, rr->resrec.name->c);
		}

	unreg_error:
	LogMsg("uDNS_UpdateRecord: Requested update of record %##s type %d, in erroneous state %d",
		   rr->resrec.name->c, rr->resrec.rrtype, rr->state);
	return mStatus_Invalid;
	}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - Periodic Execution Routines
#endif

mDNSlocal const mDNSu8 *mDNS_WABLabels[] =
	{
	(const mDNSu8 *)"\001b",
	(const mDNSu8 *)"\002db",
	(const mDNSu8 *)"\002lb",
	(const mDNSu8 *)"\001r",
	(const mDNSu8 *)"\002dr",
	(const mDNSu8 *)"\002cf",
	(const mDNSu8 *)mDNSNULL,
	};

// Returns true if it is a WAB question
mDNSlocal mDNSBool WABQuestion(const domainname *qname)
	{
 	const mDNSu8 *sd = (const mDNSu8 *)"\007_dns-sd";
	const mDNSu8 *prot = (const mDNSu8 *)"\004_udp";
	const domainname *d = qname;
	const mDNSu8 *label;
	int i = 0;

	// We need at least 3 labels (WAB prefix) + one more label to make
	// a meaningful WAB query
	if (CountLabels(qname) < 4) { debugf("WABQuestion: question %##s, not enough labels", qname->c); return mDNSfalse; }

	label = (const mDNSu8 *)d;
	while (mDNS_WABLabels[i] != (const mDNSu8 *)mDNSNULL)
		{
		if (SameDomainLabel(mDNS_WABLabels[i], label)) {debugf("WABquestion: WAB question %##s, label1 match", qname->c); break;}
		i++;
		}
	if (mDNS_WABLabels[i] == (const mDNSu8 *)mDNSNULL)
		{
		debugf("WABquestion: Not a WAB question %##s, label1 mismatch", qname->c);
		return mDNSfalse;
		}
	// CountLabels already verified the number of labels 
	d = (const domainname *)(d->c + 1 + d->c[0]);	// Second Label
	label = (const mDNSu8 *)d;
	if (!SameDomainLabel(label, sd)){ debugf("WABquestion: Not a WAB question %##s, label2 mismatch", qname->c);return(mDNSfalse); }
	debugf("WABquestion: WAB question %##s, label2 match", qname->c);

	d = (const domainname *)(d->c + 1 + d->c[0]); 	// Third Label
	label = (const mDNSu8 *)d;
	if (!SameDomainLabel(label, prot)){ debugf("WABquestion: Not a WAB question %##s, label3 mismatch", qname->c);return(mDNSfalse); }
	debugf("WABquestion: WAB question %##s, label3 match", qname->c);

	LogInfo("WABquestion: Question %##s is a WAB question", qname->c);

	return mDNStrue;
	}

// The question to be checked is not passed in as an explicit parameter;
// instead it is implicit that the question to be checked is m->CurrentQuestion.
mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
	{
	DNSQuestion *q = m->CurrentQuestion;
	if (m->timenow - NextQSendTime(q) < 0) return;

	if (q->LongLived)
		{
		switch (q->state)
			{
			case LLQ_InitialRequest:   startLLQHandshake(m, q); break;
			case LLQ_SecondaryRequest:
									   // For PrivateQueries, we need to start the handshake again as we don't do the Challenge/Response step
									   if (PrivateQuery(q))
										   startLLQHandshake(m, q);
									   else
									  	   sendChallengeResponse(m, q, mDNSNULL);
									   break;
			case LLQ_Established:      sendLLQRefresh(m, q); break;
			case LLQ_Poll:             break;	// Do nothing (handled below)
			}
		}

	// We repeat the check above (rather than just making this the "else" case) because startLLQHandshake can change q->state to LLQ_Poll
	if (!(q->LongLived && q->state != LLQ_Poll))
		{
		if (q->unansweredQueries >= MAX_UCAST_UNANSWERED_QUERIES)
			{
			DNSServer *orig = q->qDNSServer;
			if (orig)
				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);

			PenalizeDNSServer(m, q);
			q->noServerResponse = 1;
			}
		// There are two cases here.
		//
		// 1. We have only one DNS server for this question. It is not responding even after we sent MAX_UCAST_UNANSWERED_QUERIES.
		//    In that case, we need to keep retrying till we get a response. But we need to backoff as we retry. We set
		//    noServerResponse in the block above and below we do not touch the question interval. When we come here, we
		//    already waited for the response. We need to send another query right at this moment. We do that below by
		//    reinitializing dns servers and reissuing the query.
		//
		// 2. We have more than one DNS server. If at least one server did not respond, we would have set noServerResponse
		//    either now (the last server in the list) or before (non-last server in the list). In either case, if we have
		//    reached the end of DNS server list, we need to try again from the beginning. Ideally we should try just the
		//    servers that did not respond, but for simplicity we try all the servers. Once we reached the end of list, we
		//    set triedAllServersOnce so that we don't try all the servers aggressively. See PenalizeDNSServer.
		if (!q->qDNSServer && q->noServerResponse)
			{
			DNSServer *new;
			DNSQuestion *qptr;
			q->triedAllServersOnce = 1;
			// Re-initialize all DNS servers for this question. If we have a DNSServer, DNSServerChangeForQuestion will
			// handle all the work including setting the new DNS server.
			SetValidDNSServers(m, q);
			new = GetServerForQuestion(m, q);
			if (new)
				{
				LogInfo("uDNS_checkCurrentQuestion: Retrying question %p %##s (%s) DNS Server %#a:%d ThisQInterval %d",
					q, q->qname.c, DNSTypeName(q->qtype), new ? &new->addr : mDNSNULL, mDNSVal16(new ? new->port : zeroIPPort), q->ThisQInterval);
				DNSServerChangeForQuestion(m, q, new);
				}
			for (qptr = q->next ; qptr; qptr = qptr->next)
				if (qptr->DuplicateOf == q) { qptr->validDNSServers = q->validDNSServers; qptr->qDNSServer = q->qDNSServer; }
			}
		if (q->qDNSServer && q->qDNSServer->teststate != DNSServer_Disabled)
			{
			mDNSu8 *end = m->omsg.data;
			mStatus err = mStatus_NoError;
			mDNSBool private = mDNSfalse;

			InitializeDNSMessage(&m->omsg.h, q->TargetQID, uQueryFlags);

			if (q->qDNSServer->teststate != DNSServer_Untested || NoTestQuery(q))
				{
				end = putQuestion(&m->omsg, m->omsg.data, m->omsg.data + AbsoluteMaxDNSMessageData, &q->qname, q->qtype, q->qclass);
				private = PrivateQuery(q);
				}
			else if (m->timenow - q->qDNSServer->lasttest >= INIT_UCAST_POLL_INTERVAL)	// Make sure at least three seconds has elapsed since last test query
				{
				LogInfo("Sending DNS test query to %#a:%d", &q->qDNSServer->addr, mDNSVal16(q->qDNSServer->port));
				q->ThisQInterval = INIT_UCAST_POLL_INTERVAL / QuestionIntervalStep;
				q->qDNSServer->lasttest = m->timenow;
				end = putQuestion(&m->omsg, m->omsg.data, m->omsg.data + AbsoluteMaxDNSMessageData, DNSRelayTestQuestion, kDNSType_PTR, kDNSClass_IN);
				q->qDNSServer->testid = m->omsg.h.id;
				}

			if (end > m->omsg.data && (q->qDNSServer->teststate != DNSServer_Failed || NoTestQuery(q)))
				{
				//LogMsg("uDNS_CheckCurrentQuestion %p %d %p %##s (%s)", q, NextQSendTime(q) - m->timenow, private, q->qname.c, DNSTypeName(q->qtype));
				if (private)
					{
					if (q->nta) CancelGetZoneData(m, q->nta);
					q->nta = StartGetZoneData(m, &q->qname, q->LongLived ? ZoneServiceLLQ : ZoneServiceQuery, PrivateQueryGotZoneData, q);
					if (q->state == LLQ_Poll) q->ThisQInterval = (LLQ_POLL_INTERVAL + mDNSRandom(LLQ_POLL_INTERVAL/10)) / QuestionIntervalStep;
					}
				else
					{
				    debugf("uDNS_CheckCurrentQuestion sending %p %##s (%s) %#a:%d UnansweredQueries %d",
				    	q, q->qname.c, DNSTypeName(q->qtype),
				    	q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL, mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zeroIPPort), q->unansweredQueries);
					if (!q->LocalSocket) q->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
					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);
					}
				}

			if (err) debugf("ERROR: uDNS_idle - mDNSSendDNSMessage - %d", err); // surpress syslog messages if we have no network
			else
				{
				q->ThisQInterval = q->ThisQInterval * QuestionIntervalStep;	// Only increase interval if send succeeded
				q->unansweredQueries++;
				if (q->ThisQInterval > MAX_UCAST_POLL_INTERVAL)
					q->ThisQInterval = MAX_UCAST_POLL_INTERVAL;
				if (private && q->state != LLQ_Poll)
					{
					// We don't want to retransmit too soon. Hence, we always schedule our first
					// retransmisson at 3 seconds rather than one second
					if (q->ThisQInterval < (3 * mDNSPlatformOneSecond))
						q->ThisQInterval = q->ThisQInterval * QuestionIntervalStep;
					if (q->ThisQInterval > LLQ_POLL_INTERVAL)
						q->ThisQInterval = LLQ_POLL_INTERVAL;
					LogInfo("uDNS_CheckCurrentQuestion: private non polling question for %##s (%s) will be retried in %d ms", q->qname.c, DNSTypeName(q->qtype), q->ThisQInterval);
					}
				debugf("Increased ThisQInterval to %d for %##s (%s)", q->ThisQInterval, q->qname.c, DNSTypeName(q->qtype));
				}
			q->LastQTime = m->timenow;
			SetNextQueryTime(m, q);
			}
		else
			{
			// If we have no server for this query, or the only server is a disabled one, then we deliver
			// a transient failure indication to the client. This is important for things like iPhone
			// where we want to return timely feedback to the user when no network is available.
			// After calling MakeNegativeCacheRecord() we store the resulting record in the
			// cache so that it will be visible to other clients asking the same question.
			// (When we have a group of identical questions, only the active representative of the group gets
			// passed to uDNS_CheckCurrentQuestion -- we only want one set of query packets hitting the wire --
			// but we want *all* of the questions to get answer callbacks.)

			CacheRecord *rr;
			const mDNSu32 slot = HashSlot(&q->qname);
			CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
			if (cg)
				for (rr = cg->members; rr; rr=rr->next)
					if (SameNameRecordAnswersQuestion(&rr->resrec, q)) mDNS_PurgeCacheResourceRecord(m, rr);

			if (!q->qDNSServer)
				{
				if (!mDNSOpaque64IsZero(&q->validDNSServers))
					LogMsg("uDNS_CheckCurrentQuestion: ERROR!!: valid DNSServer bits not zero 0x%x, 0x%x for question %##s (%s)",
						q->validDNSServers.l[1], q->validDNSServers.l[0], q->qname.c, DNSTypeName(q->qtype));
				// If we reached the end of list while picking DNS servers, then we don't want to deactivate the
				// question. Try after 60 seconds. We find this by looking for valid DNSServers for this question,
				// if we find any, then we must have tried them before we came here. This avoids maintaining
				// another state variable to see if we had valid DNS servers for this question.
				SetValidDNSServers(m, q);	
				if (mDNSOpaque64IsZero(&q->validDNSServers))
					{
					LogInfo("uDNS_CheckCurrentQuestion: no DNS server for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
					q->ThisQInterval = 0;
					}
				else
					{
					DNSQuestion *qptr;
					// Pretend that we sent this question. As this is an ActiveQuestion, the NextScheduledQuery should
					// be set properly. Also, we need to properly backoff in cases where we don't set the question to
					// MaxQuestionInterval when we answer the question e.g., LongLived, we need to keep backing off
					q->ThisQInterval = q->ThisQInterval * QuestionIntervalStep;
					q->LastQTime = m->timenow;
					SetNextQueryTime(m, q);
					// Pick a new DNS server now. Otherwise, when the cache is 80% of its expiry, we will try
					// to send a query and come back to the same place here and log the above message.
					q->qDNSServer = GetServerForQuestion(m, q);
					for (qptr = q->next ; qptr; qptr = qptr->next)
						if (qptr->DuplicateOf == q) { qptr->validDNSServers = q->validDNSServers; qptr->qDNSServer = q->qDNSServer; }
					LogInfo("uDNS_checkCurrentQuestion: Tried all DNS servers, retry question %p SuppressUnusable %d %##s (%s) with DNS Server %#a:%d after 60 seconds, ThisQInterval %d",
						q, q->SuppressUnusable, q->qname.c, DNSTypeName(q->qtype),
						q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL, mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zeroIPPort), q->ThisQInterval);
					}
				}
			else
				{
				q->ThisQInterval = 0;
				LogMsg("uDNS_CheckCurrentQuestion DNS server %#a:%d for %##s is disabled", &q->qDNSServer->addr, mDNSVal16(q->qDNSServer->port), q->qname.c);
				}

			// For some of the WAB queries that we generate form within the mDNSResponder, most of the home routers
			// don't understand and return ServFail/NXDomain. In those cases, we don't want to try too often. We try
			// every fifteen minutes in that case
			MakeNegativeCacheRecord(m, &m->rec.r, &q->qname, q->qnamehash, q->qtype, q->qclass, (WABQuestion(&q->qname) ? 60 * 15 : 60), mDNSInterface_Any, q->qDNSServer);
			q->unansweredQueries = 0;
			// We're already using the m->CurrentQuestion pointer, so CacheRecordAdd can't use it to walk the question list.
			// To solve this problem we set rr->DelayDelivery to a nonzero value (which happens to be 'now') so that we
			// momentarily defer generating answer callbacks until mDNS_Execute time.
			CreateNewCacheEntry(m, slot, cg, NonZeroTime(m->timenow));
			ScheduleNextCacheCheckTime(m, slot, NonZeroTime(m->timenow));
			m->rec.r.resrec.RecordType = 0;		// Clear RecordType to show we're not still using it
			// MUST NOT touch m->CurrentQuestion (or q) after this -- client callback could have deleted it
			}
		}
	}

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;

	if (HaveRoutable) m->ExternalAddress = m->AdvertisedV4.ip.v4;

	if (m->NATTraversals && rfc1918)			// Do we need to open NAT-PMP socket to receive multicast announcements from router?
		{
		if (m->NATMcastRecvskt == mDNSNULL)		// If we are behind a NAT and the socket hasn't been opened yet, open it
			{
			// we need to log a message if we can't get our socket, but only the first time (after success)
			static mDNSBool needLog = mDNStrue;
			m->NATMcastRecvskt = mDNSPlatformUDPSocket(m, NATPMPAnnouncementPort);
			if (!m->NATMcastRecvskt)
				{
				if (needLog)
					{
					LogMsg("CheckNATMappings: Failed to allocate port 5350 UDP multicast socket for NAT-PMP announcements");
					needLog = mDNSfalse;
					}
				}
			else
				needLog = mDNStrue;				
			}
		}
	else										// else, we don't want to listen for announcements, so close them if they're open
		{
		if (m->NATMcastRecvskt) { mDNSPlatformUDPClose(m->NATMcastRecvskt); m->NATMcastRecvskt = mDNSNULL; }
		if (m->SSDPSocket)      { debugf("CheckNATMappings destroying SSDPSocket %p", &m->SSDPSocket); mDNSPlatformUDPClose(m->SSDPSocket); m->SSDPSocket = mDNSNULL; }
		}

	if (!m->NATTraversals)
		m->retryGetAddr = m->timenow + 0x78000000;
	else
		{
		if (m->timenow - m->retryGetAddr >= 0)
			{
			err = uDNS_SendNATMsg(m, mDNSNULL);		// Will also do UPnP discovery for us, if necessary
			if (!err)
				{
				if      (m->retryIntervalGetAddr < NATMAP_INIT_RETRY)             m->retryIntervalGetAddr = NATMAP_INIT_RETRY;
				else if (m->retryIntervalGetAddr < NATMAP_MAX_RETRY_INTERVAL / 2) m->retryIntervalGetAddr *= 2;
				else                                                              m->retryIntervalGetAddr = NATMAP_MAX_RETRY_INTERVAL;
				}
			LogInfo("CheckNATMappings retryGetAddr sent address request err %d interval %d", err, m->retryIntervalGetAddr);

			// Always update m->retryGetAddr, even if we fail to send the packet. Otherwise in cases where we can't send the packet
			// (like when we have no active interfaces) we'll spin in an infinite loop repeatedly failing to send the packet
			m->retryGetAddr = m->timenow + m->retryIntervalGetAddr;
			}
		// Even when we didn't send the GetAddr packet, still need to make sure NextScheduledNATOp is set correctly
		if (m->NextScheduledNATOp - m->retryGetAddr > 0)
			m->NextScheduledNATOp = m->retryGetAddr;
		}

	if (m->CurrentNATTraversal) LogMsg("WARNING m->CurrentNATTraversal already in use");
	m->CurrentNATTraversal = m->NATTraversals;

	while (m->CurrentNATTraversal)
		{
		NATTraversalInfo *cur = m->CurrentNATTraversal;
		m->CurrentNATTraversal = m->CurrentNATTraversal->next;

		if (HaveRoutable)		// If not RFC 1918 address, our own address and port are effectively our external address and port
			{
			cur->ExpiryTime = 0;
			cur->NewResult  = mStatus_NoError;
			}
		else if (cur->Protocol)		// Check if it's time to send port mapping packets
			{
			if (m->timenow - cur->retryPortMap >= 0)						// Time to do something with this mapping
				{
				if (cur->ExpiryTime && cur->ExpiryTime - m->timenow < 0)	// Mapping has expired
					{
					cur->ExpiryTime    = 0;
					cur->retryInterval = NATMAP_INIT_RETRY;
					}

				//LogMsg("uDNS_SendNATMsg");
				err = uDNS_SendNATMsg(m, cur);

				if (cur->ExpiryTime)						// If have active mapping then set next renewal time halfway to expiry
					NATSetNextRenewalTime(m, cur);
				else										// else no mapping; use exponential backoff sequence
					{
					if      (cur->retryInterval < NATMAP_INIT_RETRY            ) cur->retryInterval = NATMAP_INIT_RETRY;
					else if (cur->retryInterval < NATMAP_MAX_RETRY_INTERVAL / 2) cur->retryInterval *= 2;
					else                                                         cur->retryInterval = NATMAP_MAX_RETRY_INTERVAL;
					cur->retryPortMap = m->timenow + cur->retryInterval;
					}
				}

			if (m->NextScheduledNATOp - cur->retryPortMap > 0)
				m->NextScheduledNATOp = cur->retryPortMap;
			}

		// Notify the client if necessary. We invoke the callback if:
		// (1) we have an ExternalAddress, or we've tried and failed a couple of times to discover it
		// and (2) the client doesn't want a mapping, or the client won't need a mapping, or the client has a successful mapping, or we've tried and failed a couple of times
		// and (3) we have new data to give the client that's changed since the last callback
		// Time line is: Send, Wait 500ms, Send, Wait 1sec, Send, Wait 2sec, Send
		// At this point we've sent three requests without an answer, we've just sent our fourth request,
		// retryIntervalGetAddr is now 4 seconds, which is greater than NATMAP_INIT_RETRY * 8 (2 seconds),
		// so we return an error result to the caller.
		if (!mDNSIPv4AddressIsZero(m->ExternalAddress) || m->retryIntervalGetAddr > NATMAP_INIT_RETRY * 8)
			{
			const mStatus EffectiveResult = cur->NewResult ? cur->NewResult : mDNSv4AddrIsRFC1918(&m->ExternalAddress) ? mStatus_DoubleNAT : mStatus_NoError;
			const mDNSIPPort ExternalPort = HaveRoutable ? cur->IntPort :
				!mDNSIPv4AddressIsZero(m->ExternalAddress) && cur->ExpiryTime ? cur->RequestedPort : zeroIPPort;
			if (!cur->Protocol || HaveRoutable || cur->ExpiryTime || cur->retryInterval > NATMAP_INIT_RETRY * 8)
				if (!mDNSSameIPv4Address(cur->ExternalAddress, m->ExternalAddress) ||
					!mDNSSameIPPort     (cur->ExternalPort,       ExternalPort)    ||
					cur->Result != EffectiveResult)
					{
					//LogMsg("NAT callback %d %d %d", cur->Protocol, cur->ExpiryTime, cur->retryInterval);
					if (cur->Protocol && mDNSIPPortIsZero(ExternalPort) && !mDNSIPv4AddressIsZero(m->Router.ip.v4))
						{
						if (!EffectiveResult)
							LogInfo("CheckNATMapping: Failed to obtain NAT port mapping %p from router %#a external address %.4a internal port %5d interval %d error %d",
								cur, &m->Router, &m->ExternalAddress, mDNSVal16(cur->IntPort), cur->retryInterval, EffectiveResult);
						else
							LogMsg("CheckNATMapping: Failed to obtain NAT port mapping %p from router %#a external address %.4a internal port %5d interval %d error %d",
								cur, &m->Router, &m->ExternalAddress, mDNSVal16(cur->IntPort), cur->retryInterval, EffectiveResult);
						}

					cur->ExternalAddress = m->ExternalAddress;
					cur->ExternalPort    = ExternalPort;
					cur->Lifetime        = cur->ExpiryTime && !mDNSIPPortIsZero(ExternalPort) ?
						(cur->ExpiryTime - m->timenow + mDNSPlatformOneSecond/2) / mDNSPlatformOneSecond : 0;
					cur->Result          = EffectiveResult;
					mDNS_DropLockBeforeCallback();		// Allow client to legally make mDNS API calls from the callback
					if (cur->clientCallback)
						cur->clientCallback(m, cur);
					mDNS_ReclaimLockAfterCallback();	// Decrement mDNS_reentrancy to block mDNS API calls again
					// MUST NOT touch cur after invoking the callback
					}
			}
		}
	}

mDNSlocal mDNSs32 CheckRecordUpdates(mDNS *m)
	{
	AuthRecord *rr;
	mDNSs32 nextevent = m->timenow + 0x3FFFFFFF;

	CheckGroupRecordUpdates(m);

	for (rr = m->ResourceRecords; rr; rr = rr->next)
		{
		if (!AuthRecord_uDNS(rr)) continue;
		if (rr->state == regState_NoTarget) {debugf("CheckRecordUpdates: Record %##s in NoTarget", rr->resrec.name->c); continue;}
		// While we are waiting for the port mapping, we have nothing to do. The port mapping callback
		// will take care of this
		if (rr->state == regState_NATMap) {debugf("CheckRecordUpdates: Record %##s in NATMap", rr->resrec.name->c); continue;}
		if (rr->state == regState_Pending || rr->state == regState_DeregPending || rr->state == regState_UpdatePending ||
			rr->state == regState_Refresh || rr->state == regState_Registered)
			{
			if (rr->LastAPTime + rr->ThisAPInterval - m->timenow <= 0)
				{
				if (rr->tcp) { DisposeTCPConn(rr->tcp); rr->tcp = mDNSNULL; }
				if (!rr->nta || mDNSIPv4AddressIsZero(rr->nta->Addr.ip.v4))
					{
					// Zero out the updateid so that if we have a pending response from the server, it won't
					// be accepted as a valid response. If we accept the response, we might free the new "nta"
					if (rr->nta) { rr->updateid = zeroID; CancelGetZoneData(m, rr->nta); }
					rr->nta = StartGetZoneData(m, rr->resrec.name, ZoneServiceUpdate, RecordRegistrationGotZoneData, rr);

					// We have just started the GetZoneData. We need to wait for it to finish. SetRecordRetry here
					// schedules the update timer to fire in the future.
					//
					// There are three cases.
					//
					// 1) When the updates are sent the first time, the first retry is intended to be at three seconds
					//    in the future. But by calling SetRecordRetry here we set it to nine seconds. But it does not
					//    matter because when the answer comes back, RecordRegistrationGotZoneData resets the interval
					//    back to INIT_RECORD_REG_INTERVAL. This also gives enough time for the query.
					//
					// 2) In the case of update errors (updateError), this causes further backoff as
					//    RecordRegistrationGotZoneData does not reset the timer. This is intentional as in the case of
					//    errors, we don't want to update aggressively.
					//
					// 3) We might be refreshing the update. This is very similar to case (1). RecordRegistrationGotZoneData
					//    resets it back to INIT_RECORD_REG_INTERVAL.
					// 
					SetRecordRetry(m, rr, 0);
					}
				else if (rr->state == regState_DeregPending) SendRecordDeregistration(m, rr);
				else SendRecordRegistration(m, rr);
				}
			}
		if (nextevent - (rr->LastAPTime + rr->ThisAPInterval) > 0)
			nextevent = (rr->LastAPTime + rr->ThisAPInterval);
		}
	return nextevent;
	}

mDNSexport void uDNS_Tasks(mDNS *const m)
	{
	mDNSs32 nexte;
	DNSServer *d;

	m->NextuDNSEvent = m->timenow + 0x3FFFFFFF;

	nexte = CheckRecordUpdates(m);
	if (m->NextuDNSEvent - nexte > 0)
		m->NextuDNSEvent = nexte;

	for (d = m->DNSServers; d; d=d->next)
		if (d->penaltyTime)
			{
			if (m->timenow - d->penaltyTime >= 0)
				{
				LogInfo("DNS server %#a:%d out of penalty box", &d->addr, mDNSVal16(d->port));
				d->penaltyTime = 0;
				}
			else
				if (m->NextuDNSEvent - d->penaltyTime > 0)
					m->NextuDNSEvent = d->penaltyTime;
			}

	if (m->CurrentQuestion)
		LogMsg("uDNS_Tasks ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
	m->CurrentQuestion = m->Questions;
	while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
		{
		DNSQuestion *const q = m->CurrentQuestion;
		if (ActiveQuestion(q) && !mDNSOpaque16IsZero(q->TargetQID))
			{
			uDNS_CheckCurrentQuestion(m);
			if (q == m->CurrentQuestion)
				if (m->NextuDNSEvent - NextQSendTime(q) > 0)
					m->NextuDNSEvent = NextQSendTime(q);
			}
		// If m->CurrentQuestion wasn't modified out from under us, advance it now
		// We can't do this at the start of the loop because uDNS_CheckCurrentQuestion()
		// depends on having m->CurrentQuestion point to the right question
		if (m->CurrentQuestion == q)
			m->CurrentQuestion = q->next;
		}
	m->CurrentQuestion = mDNSNULL;
	}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - Startup, Shutdown, and Sleep
#endif

mDNSexport void SleepRecordRegistrations(mDNS *m)
	{
	AuthRecord *rr;
	for (rr = m->ResourceRecords; rr; rr=rr->next)
		{
		if (AuthRecord_uDNS(rr))
			{
			// Zero out the updateid so that if we have a pending response from the server, it won't
			// be accepted as a valid response.
			if (rr->nta) { rr->updateid = zeroID; CancelGetZoneData(m, rr->nta); rr->nta = mDNSNULL; }

			if (rr->NATinfo.clientContext)
				{
				mDNS_StopNATOperation_internal(m, &rr->NATinfo);
				rr->NATinfo.clientContext = mDNSNULL;
				}
			// We are waiting to update the resource record. The original data of the record is
			// in OrigRData and the updated value is in InFlightRData. Free the old and the new
			// one will be registered when we come back.
			if (rr->state == regState_UpdatePending)
				{
				// act as if the update succeeded, since we're about to delete the name anyway
				rr->state = regState_Registered;
				// deallocate old RData
				if (rr->UpdateCallback) rr->UpdateCallback(m, rr, rr->OrigRData, rr->OrigRDLen);
				SetNewRData(&rr->resrec, rr->InFlightRData, rr->InFlightRDLen);
				rr->OrigRData = mDNSNULL;
				rr->InFlightRData = mDNSNULL;
				}

			// If we have not begun the registration process i.e., never sent a registration packet,
			// then uDNS_DeregisterRecord will not send a deregistration
			uDNS_DeregisterRecord(m, rr);
			
			// When we wake, we call ActivateUnicastRegistration which starts at StartGetZoneData
			}
		}
	}

mDNSexport void mDNS_AddSearchDomain(const domainname *const domain)
	{
	SearchListElem **p;

	// Check to see if we already have this domain in our list
	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;
			LogInfo("mDNS_AddSearchDomain already in list %##s", domain->c);
			return;
			}

	// if domain not in list, add to list, mark as add (1)
	*p = mDNSPlatformMemAllocate(sizeof(SearchListElem));
	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);
	}

mDNSlocal void FreeARElemCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
	{
	(void)m;	// unused
	if (result == mStatus_MemFree) mDNSPlatformMemFree(rr->RecordContext);
	}

#if APPLE_OSX_mDNSResponder
mDNSlocal void CheckAutoTunnel6Registration(mDNS *const m, mDNSBool RegisterAutoTunnel6)
	{
	LogInfo("CheckAutoTunnel6Registration: Current value RegisterAutoTunnel6 %d, New value %d", m->RegisterAutoTunnel6, RegisterAutoTunnel6);
	if (!RegisterAutoTunnel6)
		{
		// We are not supposed to register autotunnel6. If we had previously registered
		// autotunnel6, deregister it now.
		if (m->RegisterAutoTunnel6)
			{
			m->RegisterAutoTunnel6 = mDNSfalse;
			LogInfo("CheckAutoTunnel6Registration: Removing AutoTunnel6");
			RemoveAutoTunnel6Record(m);
			}
		else LogInfo("CheckAutoTunnel6Registration: Already Removed AutoTunnel6");
		}
	else 
		{
		// We are supposed to register autotunnel6. If we had previously  de-registered
		// autotunnel6, re-register it now.
		if (!m->RegisterAutoTunnel6)
			{
			m->RegisterAutoTunnel6 = mDNStrue;
			LogInfo("CheckAutoTunnel6Registration: Adding AutoTunnel6");
			SetupConndConfigChanges(m);
			}
		else LogInfo("CheckAutoTunnel6Registration: already Added AutoTunnel6");
		}
	}
#endif

mDNSlocal void FoundDirDomain(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));
	if (answer->rrtype != kDNSType_TXT)
		{
		LogMsg("FoundDirDomain: 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);
		return;
		}
	if (answer->InterfaceID == mDNSInterface_LocalOnly)
		{
		LogInfo("FoundDirDomain: 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);
		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);
		return;
		}

	// It is sufficient for one answer to disable registration of autotunnel6. But we should
	// have zero answers across all domains to register autotunnel6.
	if (AddRecord)
		{
		slElem->numDirAnswers++;
		RegisterAutoTunnel6 = mDNSfalse;
		}
	else
		{
		const SearchListElem *s;
		slElem->numDirAnswers--;
		if (slElem->numDirAnswers < 0) LogMsg("FoundDirDomain: numDirAnswers less than zero %d", slElem->numDirAnswers);
		// See if any domain (including the slElem) has any answers
 		for (s=SearchList; s; s=s->next)
			if (s->numDirAnswers) { RegisterAutoTunnel6 = mDNSfalse; break; }
		}
#if APPLE_OSX_mDNSResponder
	CheckAutoTunnel6Registration(m, RegisterAutoTunnel6);
#endif
	}

mDNSlocal void FoundDomain(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
	{
	SearchListElem *slElem = question->QuestionContext;
	mStatus err;
	const char *name;

	if (answer->rrtype != kDNSType_PTR) return;
	if (answer->RecordType == kDNSRecordTypePacketNegative) return;
	if (answer->InterfaceID == mDNSInterface_LocalOnly) return;

	if      (question == &slElem->BrowseQ)          name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowse];
	else if (question == &slElem->DefBrowseQ)       name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowseDefault];
	else if (question == &slElem->AutomaticBrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowseAutomatic];
	else if (question == &slElem->RegisterQ)        name = mDNS_DomainTypeNames[mDNS_DomainTypeRegistration];
	else if (question == &slElem->DefRegisterQ)     name = mDNS_DomainTypeNames[mDNS_DomainTypeRegistrationDefault];
	else { LogMsg("FoundDomain - unknown question"); return; }

	LogInfo("FoundDomain: %p %s %s Q %##s A %s", answer->InterfaceID, AddRecord ? "Add" : "Rmv", name, question->qname.c, RRDisplayString(m, answer));

	if (AddRecord)
		{
		ARListElem *arElem = mDNSPlatformMemAllocate(sizeof(ARListElem));
		if (!arElem) { LogMsg("ERROR: FoundDomain out of memory"); return; }
		mDNS_SetupResourceRecord(&arElem->ar, mDNSNULL, mDNSInterface_LocalOnly, kDNSType_PTR, 7200, kDNSRecordTypeShared, FreeARElemCallback, arElem);
		MakeDomainNameFromDNSNameString(&arElem->ar.namestorage, name);
		AppendDNSNameString            (&arElem->ar.namestorage, "local");
		AssignDomainName(&arElem->ar.resrec.rdata->u.name, &answer->rdata->u.name);
		LogInfo("FoundDomain: Registering %s", ARDisplayString(m, &arElem->ar));
		err = mDNS_Register(m, &arElem->ar);
		if (err) { LogMsg("ERROR: FoundDomain - mDNS_Register returned %d", err); mDNSPlatformMemFree(arElem); return; }
		arElem->next = slElem->AuthRecs;
		slElem->AuthRecs = arElem;
		}
	else
		{
		ARListElem **ptr = &slElem->AuthRecs;
		while (*ptr)
			{
			if (SameDomainName(&(*ptr)->ar.resrec.rdata->u.name, &answer->rdata->u.name))
				{
				ARListElem *dereg = *ptr;
				*ptr = (*ptr)->next;
				LogInfo("FoundDomain: Deregistering %s", ARDisplayString(m, &dereg->ar));
				err = mDNS_Deregister(m, &dereg->ar);
				if (err) LogMsg("ERROR: FoundDomain - mDNS_Deregister returned %d", err);
				// Memory will be freed in the FreeARElemCallback
				}
			else
				ptr = &(*ptr)->next;
			}
		}
	}

#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING
mDNSexport void udns_validatelists(void *const v)
	{
	mDNS *const m = v;

	NATTraversalInfo *n;
	for (n = m->NATTraversals; n; n=n->next)
		if (n->next == (NATTraversalInfo *)~0 || n->clientCallback == (NATTraversalClientCallback)~0)
			LogMemCorruption("m->NATTraversals: %p is garbage", n);

	DNSServer *d;
	for (d = m->DNSServers; d; d=d->next)
		if (d->next == (DNSServer *)~0 || d->teststate > DNSServer_Disabled)
			LogMemCorruption("m->DNSServers: %p is garbage (%d)", d, d->teststate);

	DomainAuthInfo *info;
	for (info = m->AuthInfoList; info; info = info->next)
		if (info->next == (DomainAuthInfo *)~0 || info->AutoTunnel == (mDNSBool)~0)
			LogMemCorruption("m->AuthInfoList: %p is garbage (%X)", info, info->AutoTunnel);

	HostnameInfo *hi;
	for (hi = m->Hostnames; hi; hi = hi->next)
		if (hi->next == (HostnameInfo *)~0 || hi->StatusCallback == (mDNSRecordCallback*)~0)
			LogMemCorruption("m->Hostnames: %p is garbage", n);

	SearchListElem *ptr;
	for (ptr = SearchList; ptr; ptr = ptr->next)
		if (ptr->next == (SearchListElem *)~0 || ptr->AuthRecs == (void*)~0)
			LogMemCorruption("SearchList: %p is garbage (%X)", ptr, ptr->AuthRecs);
	}
#endif

mDNSlocal void mDNS_StartDirQuestion(mDNS *const m, DNSQuestion *question, domainname *domain, void *context)
	{
	AssignDomainName (&question->qname, (const domainname*)"\002cf" "\007_dns-sd" "\x04_udp");
	AppendDomainName (&question->qname, domain);
	question->InterfaceID      = mDNSInterface_Any;
	question->Target           = zeroAddr;
	question->qtype            = kDNSType_TXT;
	question->qclass           = kDNSClass_IN;
	question->LongLived        = mDNSfalse;
	question->ExpectUnique     = mDNStrue;
	question->ForceMCast       = mDNSfalse;
	question->ReturnIntermed   = mDNSfalse;
	question->SuppressUnusable = mDNSfalse;
	question->QuestionCallback = FoundDirDomain;
	question->QuestionContext  = context;
	LogInfo("mDNS_StartDirQuestion: Start DIR domain question %##s", question->qname.c);
	if (mDNS_StartQuery(m, question))
		LogMsg("mDNS_StartDirQuestion: ERROR!! cannot start _dir._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)
	{
	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;

	// 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);
	mDNS_Unlock(m);

	// 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
			{
			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)
			// 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))
				{
				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);
				}
			mDNSPlatformMemFree(ptr);

	        // deregister records generated from answers to the query
			while (arList)
				{
				ARListElem *dereg = arList;
				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);
				// Memory will be freed in the FreeARElemCallback
				}
			continue;
			}

		if (ptr->flag == 1)	// add
			{
			// 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;
				err1 = mDNS_GetDomains(m, &ptr->BrowseQ,          mDNS_DomainTypeBrowse,              &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
				err2 = mDNS_GetDomains(m, &ptr->DefBrowseQ,       mDNS_DomainTypeBrowseDefault,       &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
				err3 = mDNS_GetDomains(m, &ptr->RegisterQ,        mDNS_DomainTypeRegistration,        &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
				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"
						   "%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 = 0;
			}

		if (ptr->flag) { LogMsg("uDNS_RegisterSearchDomains - unknown flag %d. Skipping.", ptr->flag); }

		p = &ptr->next;
		}
	// 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 APPLE_OSX_mDNSResponder
	CheckAutoTunnel6Registration(m, RegisterAutoTunnel6);
#endif
	return mStatus_NoError;
	}

// Construction of Default Browse domain list (i.e. when clients pass NULL) is as follows:
// 1) query for b._dns-sd._udp.local on LocalOnly interface
//    (.local manually generated via explicit callback)
// 2) for each search domain (from prefs pane), query for b._dns-sd._udp.<searchdomain>.
// 3) for each result from (2), register LocalOnly PTR record b._dns-sd._udp.local. -> <result>
// 4) result above should generate a callback from question in (1).  result added to global list
// 5) global list delivered to client via GetSearchDomainList()
// 6) client calls to enumerate domains now go over LocalOnly interface
//    (!!!KRS may add outgoing interface in addition)

struct CompileTimeAssertionChecks_uDNS
	{
	// Check our structures are reasonable sizes. Including overly-large buffers, or embedding
	// other overly-large structures instead of having a pointer to them, can inadvertently
	// cause structure sizes (and therefore memory usage) to balloon unreasonably.
	char sizecheck_tcpInfo_t     [(sizeof(tcpInfo_t)      <=  9056) ? 1 : -1];
	char sizecheck_SearchListElem[(sizeof(SearchListElem) <=  4800) ? 1 : -1];
	};
