Home | History | Annotate | Download | only in mDNSCore
      1 /* -*- Mode: C; tab-width: 4 -*-
      2  *
      3  * Copyright (c) 2002-2006 Apple Computer, Inc. All rights reserved.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  *
     17  * This code is completely 100% portable C. It does not depend on any external header files
     18  * from outside the mDNS project -- all the types it expects to find are defined right here.
     19  *
     20  * The previous point is very important: This file does not depend on any external
     21  * header files. It should compile on *any* platform that has a C compiler, without
     22  * making *any* assumptions about availability of so-called "standard" C functions,
     23  * routines, or types (which may or may not be present on any given platform).
     24 
     25  * Formatting notes:
     26  * This code follows the "Whitesmiths style" C indentation rules. Plenty of discussion
     27  * on C indentation can be found on the web, such as <http://www.kafejo.com/komp/1tbs.htm>,
     28  * but for the sake of brevity here I will say just this: Curly braces are not syntactially
     29  * part of an "if" statement; they are the beginning and ending markers of a compound statement;
     30  * therefore common sense dictates that if they are part of a compound statement then they
     31  * should be indented to the same level as everything else in that compound statement.
     32  * Indenting curly braces at the same level as the "if" implies that curly braces are
     33  * part of the "if", which is false. (This is as misleading as people who write "char* x,y;"
     34  * thinking that variables x and y are both of type "char*" -- and anyone who doesn't
     35  * understand why variable y is not of type "char*" just proves the point that poor code
     36  * layout leads people to unfortunate misunderstandings about how the C language really works.)
     37  */
     38 
     39 #include "DNSCommon.h"                  // Defines general DNS untility routines
     40 #include "uDNS.h"						// Defines entry points into unicast-specific routines
     41 
     42 // Disable certain benign warnings with Microsoft compilers
     43 #if(defined(_MSC_VER))
     44 	// Disable "conditional expression is constant" warning for debug macros.
     45 	// Otherwise, this generates warnings for the perfectly natural construct "while(1)"
     46 	// If someone knows a variant way of writing "while(1)" that doesn't generate warning messages, please let us know
     47 	#pragma warning(disable:4127)
     48 
     49 	// Disable "assignment within conditional expression".
     50 	// Other compilers understand the convention that if you place the assignment expression within an extra pair
     51 	// of parentheses, this signals to the compiler that you really intended an assignment and no warning is necessary.
     52 	// The Microsoft compiler doesn't understand this convention, so in the absense of any other way to signal
     53 	// to the compiler that the assignment is intentional, we have to just turn this warning off completely.
     54 	#pragma warning(disable:4706)
     55 #endif
     56 
     57 #if APPLE_OSX_mDNSResponder
     58 
     59 #include <WebFilterDNS/WebFilterDNS.h>
     60 
     61 #if ! NO_WCF
     62 WCFConnection *WCFConnectionNew(void) __attribute__((weak_import));
     63 void WCFConnectionDealloc(WCFConnection* c) __attribute__((weak_import));
     64 
     65 // Do we really need to define a macro for "if"?
     66 #define CHECK_WCF_FUNCTION(X) if (X)
     67 #endif // ! NO_WCF
     68 
     69 #else
     70 
     71 #define NO_WCF 1
     72 #endif // APPLE_OSX_mDNSResponder
     73 
     74 // Forward declarations
     75 mDNSlocal void BeginSleepProcessing(mDNS *const m);
     76 mDNSlocal void RetrySPSRegistrations(mDNS *const m);
     77 mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAddr *EthAddr, mDNSOpaque48 *password);
     78 mDNSlocal mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
     79 mDNSlocal mDNSBool LocalRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
     80 mDNSlocal void mDNS_PurgeBeforeResolve(mDNS *const m, DNSQuestion *q);
     81 
     82 // ***************************************************************************
     83 #if COMPILER_LIKES_PRAGMA_MARK
     84 #pragma mark - Program Constants
     85 #endif
     86 
     87 #define NO_HINFO 1
     88 
     89 
     90 // Any records bigger than this are considered 'large' records
     91 #define SmallRecordLimit 1024
     92 
     93 #define kMaxUpdateCredits 10
     94 #define kUpdateCreditRefreshInterval (mDNSPlatformOneSecond * 6)
     95 
     96 mDNSexport const char *const mDNS_DomainTypeNames[] =
     97 	{
     98 	 "b._dns-sd._udp.",		// Browse
     99 	"db._dns-sd._udp.",		// Default Browse
    100 	"lb._dns-sd._udp.",		// Automatic Browse
    101 	 "r._dns-sd._udp.",		// Registration
    102 	"dr._dns-sd._udp."		// Default Registration
    103 	};
    104 
    105 #ifdef UNICAST_DISABLED
    106 #define uDNS_IsActiveQuery(q, u) mDNSfalse
    107 #endif
    108 
    109 // ***************************************************************************
    110 #if COMPILER_LIKES_PRAGMA_MARK
    111 #pragma mark -
    112 #pragma mark - General Utility Functions
    113 #endif
    114 
    115 // If there is a authoritative LocalOnly record that answers questions of type A, AAAA and CNAME
    116 // this returns true. Main use is to handle /etc/hosts records.
    117 #define LORecordAnswersAddressType(rr) ((rr)->ARType == AuthRecordLocalOnly && \
    118 									(rr)->resrec.RecordType & kDNSRecordTypeUniqueMask && \
    119 									((rr)->resrec.rrtype == kDNSType_A || (rr)->resrec.rrtype == kDNSType_AAAA || \
    120 									(rr)->resrec.rrtype == kDNSType_CNAME))
    121 
    122 #define FollowCNAME(q, rr, AddRecord)	(AddRecord && (q)->qtype != kDNSType_CNAME && \
    123 										(rr)->RecordType != kDNSRecordTypePacketNegative && \
    124 										(rr)->rrtype == kDNSType_CNAME)
    125 
    126 mDNSlocal void SetNextQueryStopTime(mDNS *const m, const DNSQuestion *const q)
    127 	{
    128 	if (m->mDNS_busy != m->mDNS_reentrancy+1)
    129 		LogMsg("SetNextQueryTime: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
    130 
    131 #if ForceAlerts
    132 	if (m->mDNS_busy != m->mDNS_reentrancy+1) *(long*)0 = 0;
    133 #endif
    134 
    135 	if (m->NextScheduledStopTime - q->StopTime > 0)
    136 		m->NextScheduledStopTime = q->StopTime;
    137 	}
    138 
    139 mDNSexport void SetNextQueryTime(mDNS *const m, const DNSQuestion *const q)
    140 	{
    141 	if (m->mDNS_busy != m->mDNS_reentrancy+1)
    142 		LogMsg("SetNextQueryTime: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
    143 
    144 #if ForceAlerts
    145 	if (m->mDNS_busy != m->mDNS_reentrancy+1) *(long*)0 = 0;
    146 #endif
    147 
    148 	if (ActiveQuestion(q))
    149 		{
    150 		// Depending on whether this is a multicast or unicast question we want to set either:
    151 		// m->NextScheduledQuery = NextQSendTime(q) or
    152 		// m->NextuDNSEvent      = NextQSendTime(q)
    153 		mDNSs32 *const timer = mDNSOpaque16IsZero(q->TargetQID) ? &m->NextScheduledQuery : &m->NextuDNSEvent;
    154 		if (*timer - NextQSendTime(q) > 0)
    155 			*timer = NextQSendTime(q);
    156 		}
    157 	}
    158 
    159 mDNSlocal void ReleaseAuthEntity(AuthHash *r, AuthEntity *e)
    160 	{
    161 #if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
    162 	unsigned int i;
    163 	for (i=0; i<sizeof(*e); i++) ((char*)e)[i] = 0xFF;
    164 #endif
    165 	e->next = r->rrauth_free;
    166 	r->rrauth_free = e;
    167 	r->rrauth_totalused--;
    168 	}
    169 
    170 mDNSlocal void ReleaseAuthGroup(AuthHash *r, AuthGroup **cp)
    171 	{
    172 	AuthEntity *e = (AuthEntity *)(*cp);
    173 	LogMsg("ReleaseAuthGroup:  Releasing AuthGroup %##s", (*cp)->name->c);
    174 	if ((*cp)->rrauth_tail != &(*cp)->members)
    175 		LogMsg("ERROR: (*cp)->members == mDNSNULL but (*cp)->rrauth_tail != &(*cp)->members)");
    176 	if ((*cp)->name != (domainname*)((*cp)->namestorage)) mDNSPlatformMemFree((*cp)->name);
    177 	(*cp)->name = mDNSNULL;
    178 	*cp = (*cp)->next;			// Cut record from list
    179 	ReleaseAuthEntity(r, e);
    180 	}
    181 
    182 mDNSlocal AuthEntity *GetAuthEntity(AuthHash *r, const AuthGroup *const PreserveAG)
    183 	{
    184 	AuthEntity *e = mDNSNULL;
    185 
    186 	if (r->rrauth_lock) { LogMsg("GetFreeCacheRR ERROR! Cache already locked!"); return(mDNSNULL); }
    187 	r->rrauth_lock = 1;
    188 
    189 	if (!r->rrauth_free)
    190 		{
    191 		// We allocate just one AuthEntity at a time because we need to be able
    192 		// free them all individually which normally happens when we parse /etc/hosts into
    193 		// AuthHash where we add the "new" entries and discard (free) the already added
    194 		// entries. If we allocate as chunks, we can't free them individually.
    195 		AuthEntity *storage = mDNSPlatformMemAllocate(sizeof(AuthEntity));
    196 		storage->next = mDNSNULL;
    197 		r->rrauth_free = storage;
    198 		}
    199 
    200 	// If we still have no free records, recycle all the records we can.
    201 	// Enumerating the entire auth is moderately expensive, so when we do it, we reclaim all the records we can in one pass.
    202 	if (!r->rrauth_free)
    203 		{
    204 		mDNSu32 oldtotalused = r->rrauth_totalused;
    205 		mDNSu32 slot;
    206 		for (slot = 0; slot < AUTH_HASH_SLOTS; slot++)
    207 			{
    208 			AuthGroup **cp = &r->rrauth_hash[slot];
    209 			while (*cp)
    210 				{
    211 				if ((*cp)->members || (*cp)==PreserveAG) cp=&(*cp)->next;
    212 				else ReleaseAuthGroup(r, cp);
    213 				}
    214 			}
    215 		LogInfo("GetAuthEntity: Recycled %d records to reduce auth cache from %d to %d",
    216 			oldtotalused - r->rrauth_totalused, oldtotalused, r->rrauth_totalused);
    217 		}
    218 
    219 	if (r->rrauth_free)	// If there are records in the free list, take one
    220 		{
    221 		e = r->rrauth_free;
    222 		r->rrauth_free = e->next;
    223 		if (++r->rrauth_totalused >= r->rrauth_report)
    224 			{
    225 			LogInfo("RR Auth now using %ld objects", r->rrauth_totalused);
    226 			if      (r->rrauth_report <  100) r->rrauth_report += 10;
    227 			else if (r->rrauth_report < 1000) r->rrauth_report += 100;
    228 			else                               r->rrauth_report += 1000;
    229 			}
    230 		mDNSPlatformMemZero(e, sizeof(*e));
    231 		}
    232 
    233 	r->rrauth_lock = 0;
    234 
    235 	return(e);
    236 	}
    237 
    238 mDNSexport AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name)
    239 	{
    240 	AuthGroup *ag;
    241 	for (ag = r->rrauth_hash[slot]; ag; ag=ag->next)
    242 		if (ag->namehash == namehash && SameDomainName(ag->name, name))
    243 			break;
    244 	return(ag);
    245 	}
    246 
    247 mDNSexport AuthGroup *AuthGroupForRecord(AuthHash *r, const mDNSu32 slot, const ResourceRecord *const rr)
    248 	{
    249 	return(AuthGroupForName(r, slot, rr->namehash, rr->name));
    250 	}
    251 
    252 mDNSlocal AuthGroup *GetAuthGroup(AuthHash *r, const mDNSu32 slot, const ResourceRecord *const rr)
    253 	{
    254 	mDNSu16 namelen = DomainNameLength(rr->name);
    255 	AuthGroup *ag = (AuthGroup*)GetAuthEntity(r, mDNSNULL);
    256 	if (!ag) { LogMsg("GetAuthGroup: Failed to allocate memory for %##s", rr->name->c); return(mDNSNULL); }
    257 	ag->next         = r->rrauth_hash[slot];
    258 	ag->namehash     = rr->namehash;
    259 	ag->members      = mDNSNULL;
    260 	ag->rrauth_tail  = &ag->members;
    261 	ag->name         = (domainname*)ag->namestorage;
    262 	ag->NewLocalOnlyRecords = mDNSNULL;
    263 	if (namelen > InlineCacheGroupNameSize) ag->name = mDNSPlatformMemAllocate(namelen);
    264 	if (!ag->name)
    265 		{
    266 		LogMsg("GetAuthGroup: Failed to allocate name storage for %##s", rr->name->c);
    267 		ReleaseAuthEntity(r, (AuthEntity*)ag);
    268 		return(mDNSNULL);
    269 		}
    270 	AssignDomainName(ag->name, rr->name);
    271 
    272 	if (AuthGroupForRecord(r, slot, rr)) LogMsg("GetAuthGroup: Already have AuthGroup for %##s", rr->name->c);
    273 	r->rrauth_hash[slot] = ag;
    274 	if (AuthGroupForRecord(r, slot, rr) != ag) LogMsg("GetAuthGroup: Not finding AuthGroup for %##s", rr->name->c);
    275 
    276 	return(ag);
    277 	}
    278 
    279 // Returns the AuthGroup in which the AuthRecord was inserted
    280 mDNSexport AuthGroup *InsertAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr)
    281 	{
    282 	AuthGroup *ag;
    283 	const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
    284 	ag = AuthGroupForRecord(r, slot, &rr->resrec);
    285 	if (!ag) ag = GetAuthGroup(r, slot, &rr->resrec);	// If we don't have a AuthGroup for this name, make one now
    286 	if (ag)
    287 		{
    288 		LogInfo("InsertAuthRecord: inserting auth record %s from table", ARDisplayString(m, rr));
    289 		*(ag->rrauth_tail) = rr;				// Append this record to tail of cache slot list
    290 		ag->rrauth_tail = &(rr->next);			// Advance tail pointer
    291 		}
    292 	return ag;
    293 	}
    294 
    295 mDNSexport AuthGroup *RemoveAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr)
    296 	{
    297 	AuthGroup *a;
    298 	AuthGroup **ag = &a;
    299 	AuthRecord **rp;
    300 	const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
    301 
    302 	a = AuthGroupForRecord(r, slot, &rr->resrec);
    303 	if (!a) { LogMsg("RemoveAuthRecord: ERROR!! AuthGroup not found for %s", ARDisplayString(m, rr)); return mDNSNULL; }
    304 	rp = &(*ag)->members;
    305 	while (*rp)
    306 		{
    307 		if (*rp != rr)
    308 			rp=&(*rp)->next;
    309 		else
    310 			{
    311 			// We don't break here, so that we can set the tail below without tracking "prev" pointers
    312 
    313 			LogInfo("RemoveAuthRecord: removing auth record %s from table", ARDisplayString(m, rr));
    314 			*rp = (*rp)->next;			// Cut record from list
    315 			}
    316 		}
    317 	// TBD: If there are no more members, release authgroup ?
    318 	(*ag)->rrauth_tail = rp;
    319 	return a;
    320 	}
    321 
    322 mDNSexport CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name)
    323 	{
    324 	CacheGroup *cg;
    325 	for (cg = m->rrcache_hash[slot]; cg; cg=cg->next)
    326 		if (cg->namehash == namehash && SameDomainName(cg->name, name))
    327 			break;
    328 	return(cg);
    329 	}
    330 
    331 mDNSlocal CacheGroup *CacheGroupForRecord(const mDNS *const m, const mDNSu32 slot, const ResourceRecord *const rr)
    332 	{
    333 	return(CacheGroupForName(m, slot, rr->namehash, rr->name));
    334 	}
    335 
    336 mDNSexport mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr)
    337 	{
    338 	NetworkInterfaceInfo *intf;
    339 
    340 	if (addr->type == mDNSAddrType_IPv4)
    341 		{
    342 		// Normally we resist touching the NotAnInteger fields, but here we're doing tricky bitwise masking so we make an exception
    343 		if (mDNSv4AddressIsLinkLocal(&addr->ip.v4)) return(mDNStrue);
    344 		for (intf = m->HostInterfaces; intf; intf = intf->next)
    345 			if (intf->ip.type == addr->type && intf->InterfaceID == InterfaceID && intf->McastTxRx)
    346 				if (((intf->ip.ip.v4.NotAnInteger ^ addr->ip.v4.NotAnInteger) & intf->mask.ip.v4.NotAnInteger) == 0)
    347 					return(mDNStrue);
    348 		}
    349 
    350 	if (addr->type == mDNSAddrType_IPv6)
    351 		{
    352 		if (mDNSv6AddressIsLinkLocal(&addr->ip.v6)) return(mDNStrue);
    353 		for (intf = m->HostInterfaces; intf; intf = intf->next)
    354 			if (intf->ip.type == addr->type && intf->InterfaceID == InterfaceID && intf->McastTxRx)
    355 				if ((((intf->ip.ip.v6.l[0] ^ addr->ip.v6.l[0]) & intf->mask.ip.v6.l[0]) == 0) &&
    356 					(((intf->ip.ip.v6.l[1] ^ addr->ip.v6.l[1]) & intf->mask.ip.v6.l[1]) == 0) &&
    357 					(((intf->ip.ip.v6.l[2] ^ addr->ip.v6.l[2]) & intf->mask.ip.v6.l[2]) == 0) &&
    358 					(((intf->ip.ip.v6.l[3] ^ addr->ip.v6.l[3]) & intf->mask.ip.v6.l[3]) == 0))
    359 						return(mDNStrue);
    360 		}
    361 
    362 	return(mDNSfalse);
    363 	}
    364 
    365 mDNSlocal NetworkInterfaceInfo *FirstInterfaceForID(mDNS *const m, const mDNSInterfaceID InterfaceID)
    366 	{
    367 	NetworkInterfaceInfo *intf = m->HostInterfaces;
    368 	while (intf && intf->InterfaceID != InterfaceID) intf = intf->next;
    369 	return(intf);
    370 	}
    371 
    372 mDNSexport char *InterfaceNameForID(mDNS *const m, const mDNSInterfaceID InterfaceID)
    373 	{
    374 	NetworkInterfaceInfo *intf = FirstInterfaceForID(m, InterfaceID);
    375 	return(intf ? intf->ifname : mDNSNULL);
    376 	}
    377 
    378 // Caller should hold the lock
    379 mDNSlocal void GenerateNegativeResponse(mDNS *const m)
    380 	{
    381 	DNSQuestion *q;
    382 	if (!m->CurrentQuestion) { LogMsg("GenerateNegativeResponse: ERROR!! CurrentQuestion not set"); return; }
    383 	q = m->CurrentQuestion;
    384 	LogInfo("GenerateNegativeResponse: Generating negative response for question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
    385 
    386 	MakeNegativeCacheRecord(m, &m->rec.r, &q->qname, q->qnamehash, q->qtype, q->qclass, 60, mDNSInterface_Any, mDNSNULL);
    387 	AnswerCurrentQuestionWithResourceRecord(m, &m->rec.r, QC_addnocache);
    388 	if (m->CurrentQuestion == q) { q->ThisQInterval = 0; }				// Deactivate this question
    389 	// Don't touch the question after this
    390 	m->rec.r.resrec.RecordType = 0;		// Clear RecordType to show we're not still using it
    391 	}
    392 
    393 mDNSlocal void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, ResourceRecord *rr)
    394 	{
    395 	const mDNSBool selfref = SameDomainName(&q->qname, &rr->rdata->u.name);
    396 	if (q->CNAMEReferrals >= 10 || selfref)
    397 		LogMsg("AnswerQuestionByFollowingCNAME: %p %##s (%s) NOT following CNAME referral %d%s for %s",
    398 			q, q->qname.c, DNSTypeName(q->qtype), q->CNAMEReferrals, selfref ? " (Self-Referential)" : "", RRDisplayString(m, rr));
    399 	else
    400 		{
    401 		const mDNSu32 c = q->CNAMEReferrals + 1;		// Stash a copy of the new q->CNAMEReferrals value
    402 
    403 		// The SameDomainName check above is to ignore bogus CNAME records that point right back at
    404 		// themselves. Without that check we can get into a case where we have two duplicate questions,
    405 		// A and B, and when we stop question A, UpdateQuestionDuplicates copies the value of CNAMEReferrals
    406 		// from A to B, and then A is re-appended to the end of the list as a duplicate of B (because
    407 		// the target name is still the same), and then when we stop question B, UpdateQuestionDuplicates
    408 		// copies the B's value of CNAMEReferrals back to A, and we end up not incrementing CNAMEReferrals
    409 		// for either of them. This is not a problem for CNAME loops of two or more records because in
    410 		// those cases the newly re-appended question A has a different target name and therefore cannot be
    411 		// a duplicate of any other question ('B') which was itself a duplicate of the previous question A.
    412 
    413 		// Right now we just stop and re-use the existing query. If we really wanted to be 100% perfect,
    414 		// and track CNAMEs coming and going, we should really create a subordinate query here,
    415 		// which we would subsequently cancel and retract if the CNAME referral record were removed.
    416 		// In reality this is such a corner case we'll ignore it until someone actually needs it.
    417 
    418 		LogInfo("AnswerQuestionByFollowingCNAME: %p %##s (%s) following CNAME referral %d for %s",
    419 			q, q->qname.c, DNSTypeName(q->qtype), q->CNAMEReferrals, RRDisplayString(m, rr));
    420 
    421 		mDNS_StopQuery_internal(m, q);								// Stop old query
    422 		AssignDomainName(&q->qname, &rr->rdata->u.name);			// Update qname
    423 		q->qnamehash = DomainNameHashValue(&q->qname);				// and namehash
    424 		// If a unicast query results in a CNAME that points to a .local, we need to re-try
    425 		// this as unicast. Setting the mDNSInterface_Unicast tells mDNS_StartQuery_internal
    426 		// to try this as unicast query even though it is a .local name
    427 		if (!mDNSOpaque16IsZero(q->TargetQID) && IsLocalDomain(&q->qname))
    428 			{
    429 			LogInfo("AnswerQuestionByFollowingCNAME: Resolving a .local CNAME %p %##s (%s) Record %s",
    430 				q, q->qname.c, DNSTypeName(q->qtype), RRDisplayString(m, rr));
    431 			q->InterfaceID = mDNSInterface_Unicast;
    432 			}
    433 		mDNS_StartQuery_internal(m, q);								// start new query
    434 		// Record how many times we've done this. We need to do this *after* mDNS_StartQuery_internal,
    435 		// because mDNS_StartQuery_internal re-initializes CNAMEReferrals to zero
    436 		q->CNAMEReferrals = c;
    437 		}
    438 	}
    439 
    440 // For a single given DNSQuestion pointed to by CurrentQuestion, deliver an add/remove result for the single given AuthRecord
    441 // Note: All the callers should use the m->CurrentQuestion to see if the question is still valid or not
    442 mDNSlocal void AnswerLocalQuestionWithLocalAuthRecord(mDNS *const m, AuthRecord *rr, QC_result AddRecord)
    443 	{
    444 	DNSQuestion *q = m->CurrentQuestion;
    445 	mDNSBool followcname;
    446 
    447 	if (!q)
    448 		{
    449 		LogMsg("AnswerLocalQuestionWithLocalAuthRecord: ERROR!! CurrentQuestion NULL while answering with %s", ARDisplayString(m, rr));
    450 		return;
    451 		}
    452 
    453 	followcname = FollowCNAME(q, &rr->resrec, AddRecord);
    454 
    455 	// We should not be delivering results for record types Unregistered, Deregistering, and (unverified) Unique
    456 	if (!(rr->resrec.RecordType & kDNSRecordTypeActiveMask))
    457 		{
    458 		LogMsg("AnswerLocalQuestionWithLocalAuthRecord: *NOT* delivering %s event for local record type %X %s",
    459 			AddRecord ? "Add" : "Rmv", rr->resrec.RecordType, ARDisplayString(m, rr));
    460 		return;
    461 		}
    462 
    463 	// Indicate that we've given at least one positive answer for this record, so we should be prepared to send a goodbye for it
    464 	if (AddRecord) rr->AnsweredLocalQ = mDNStrue;
    465 	mDNS_DropLockBeforeCallback();		// Allow client to legally make mDNS API calls from the callback
    466 	if (q->QuestionCallback && !q->NoAnswer)
    467 		{
    468 		q->CurrentAnswers += AddRecord ? 1 : -1;
    469  		if (LORecordAnswersAddressType(rr))
    470 			{
    471 			if (!followcname || q->ReturnIntermed)
    472 				{
    473 				// Don't send this packet on the wire as we answered from /etc/hosts
    474 				q->ThisQInterval = 0;
    475 				q->LOAddressAnswers += AddRecord ? 1 : -1;
    476 				q->QuestionCallback(m, q, &rr->resrec, AddRecord);
    477 				}
    478 			mDNS_ReclaimLockAfterCallback();	// Decrement mDNS_reentrancy to block mDNS API calls again
    479 			// The callback above could have caused the question to stop. Detect that
    480 			// using m->CurrentQuestion
    481 			if (followcname && m->CurrentQuestion == q)
    482 				AnswerQuestionByFollowingCNAME(m, q, &rr->resrec);
    483 			return;
    484 			}
    485 		else
    486 			q->QuestionCallback(m, q, &rr->resrec, AddRecord);
    487 		}
    488 	mDNS_ReclaimLockAfterCallback();	// Decrement mDNS_reentrancy to block mDNS API calls again
    489 	}
    490 
    491 mDNSlocal void AnswerInterfaceAnyQuestionsWithLocalAuthRecord(mDNS *const m, AuthRecord *rr, QC_result AddRecord)
    492  	{
    493  	if (m->CurrentQuestion)
    494  		LogMsg("AnswerInterfaceAnyQuestionsWithLocalAuthRecord: ERROR m->CurrentQuestion already set: %##s (%s)",
    495  			m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
    496  	m->CurrentQuestion = m->Questions;
    497  	while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
    498  		{
    499 		mDNSBool answered;
    500  		DNSQuestion *q = m->CurrentQuestion;
    501 		if (RRAny(rr))
    502 			answered = ResourceRecordAnswersQuestion(&rr->resrec, q);
    503 		else
    504 			answered = LocalOnlyRecordAnswersQuestion(rr, q);
    505  		if (answered)
    506  			AnswerLocalQuestionWithLocalAuthRecord(m, rr, AddRecord);		// MUST NOT dereference q again
    507 		if (m->CurrentQuestion == q)	// If m->CurrentQuestion was not auto-advanced, do it ourselves now
    508 			m->CurrentQuestion = q->next;
    509  		}
    510  	m->CurrentQuestion = mDNSNULL;
    511  	}
    512 
    513 // When a new local AuthRecord is created or deleted, AnswerAllLocalQuestionsWithLocalAuthRecord()
    514 // delivers the appropriate add/remove events to listening questions:
    515 // 1. It runs though all our LocalOnlyQuestions delivering answers as appropriate,
    516 //    stopping if it reaches a NewLocalOnlyQuestion -- brand-new questions are handled by AnswerNewLocalOnlyQuestion().
    517 // 2. If the AuthRecord is marked mDNSInterface_LocalOnly or mDNSInterface_P2P, then it also runs though
    518 //    our main question list, delivering answers to mDNSInterface_Any questions as appropriate,
    519 //    stopping if it reaches a NewQuestion -- brand-new questions are handled by AnswerNewQuestion().
    520 //
    521 // AnswerAllLocalQuestionsWithLocalAuthRecord is used by the m->NewLocalRecords loop in mDNS_Execute(),
    522 // and by mDNS_Deregister_internal()
    523 
    524 mDNSlocal void AnswerAllLocalQuestionsWithLocalAuthRecord(mDNS *const m, AuthRecord *rr, QC_result AddRecord)
    525 	{
    526 	if (m->CurrentQuestion)
    527 		LogMsg("AnswerAllLocalQuestionsWithLocalAuthRecord ERROR m->CurrentQuestion already set: %##s (%s)",
    528 			m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
    529 
    530 	m->CurrentQuestion = m->LocalOnlyQuestions;
    531 	while (m->CurrentQuestion && m->CurrentQuestion != m->NewLocalOnlyQuestions)
    532 		{
    533 		mDNSBool answered;
    534 		DNSQuestion *q = m->CurrentQuestion;
    535 		// We are called with both LocalOnly/P2P record or a regular AuthRecord
    536 		if (RRAny(rr))
    537 			answered = ResourceRecordAnswersQuestion(&rr->resrec, q);
    538 		else
    539 			answered = LocalOnlyRecordAnswersQuestion(rr, q);
    540 		if (answered)
    541 			AnswerLocalQuestionWithLocalAuthRecord(m, rr, AddRecord);			// MUST NOT dereference q again
    542 		if (m->CurrentQuestion == q)	// If m->CurrentQuestion was not auto-advanced, do it ourselves now
    543 			m->CurrentQuestion = q->next;
    544 		}
    545 
    546 	m->CurrentQuestion = mDNSNULL;
    547 
    548 	// If this AuthRecord is marked LocalOnly or P2P, then we want to deliver it to all local 'mDNSInterface_Any' questions
    549 	if (rr->ARType == AuthRecordLocalOnly || rr->ARType == AuthRecordP2P)
    550 		AnswerInterfaceAnyQuestionsWithLocalAuthRecord(m, rr, AddRecord);
    551 
    552 	}
    553 
    554 // ***************************************************************************
    555 #if COMPILER_LIKES_PRAGMA_MARK
    556 #pragma mark -
    557 #pragma mark - Resource Record Utility Functions
    558 #endif
    559 
    560 #define RRTypeIsAddressType(T) ((T) == kDNSType_A || (T) == kDNSType_AAAA)
    561 
    562 #define ResourceRecordIsValidAnswer(RR) ( ((RR)->             resrec.RecordType & kDNSRecordTypeActiveMask)  && \
    563 		((RR)->Additional1 == mDNSNULL || ((RR)->Additional1->resrec.RecordType & kDNSRecordTypeActiveMask)) && \
    564 		((RR)->Additional2 == mDNSNULL || ((RR)->Additional2->resrec.RecordType & kDNSRecordTypeActiveMask)) && \
    565 		((RR)->DependentOn == mDNSNULL || ((RR)->DependentOn->resrec.RecordType & kDNSRecordTypeActiveMask))  )
    566 
    567 #define ResourceRecordIsValidInterfaceAnswer(RR, INTID) \
    568 	(ResourceRecordIsValidAnswer(RR) && \
    569 	((RR)->resrec.InterfaceID == mDNSInterface_Any || (RR)->resrec.InterfaceID == (INTID)))
    570 
    571 #define DefaultProbeCountForTypeUnique ((mDNSu8)3)
    572 #define DefaultProbeCountForRecordType(X)      ((X) == kDNSRecordTypeUnique ? DefaultProbeCountForTypeUnique : (mDNSu8)0)
    573 
    574 #define InitialAnnounceCount ((mDNSu8)8)
    575 
    576 // For goodbye packets we set the count to 3, and for wakeups we set it to 18
    577 // (which will be up to 15 wakeup attempts over the course of 30 seconds,
    578 // and then if the machine fails to wake, 3 goodbye packets).
    579 #define GoodbyeCount ((mDNSu8)3)
    580 #define WakeupCount ((mDNSu8)18)
    581 
    582 // Number of wakeups we send if WakeOnResolve is set in the question
    583 #define InitialWakeOnResolveCount ((mDNSu8)3)
    584 
    585 // Note that the announce intervals use exponential backoff, doubling each time. The probe intervals do not.
    586 // This means that because the announce interval is doubled after sending the first packet, the first
    587 // observed on-the-wire inter-packet interval between announcements is actually one second.
    588 // The half-second value here may be thought of as a conceptual (non-existent) half-second delay *before* the first packet is sent.
    589 #define DefaultProbeIntervalForTypeUnique (mDNSPlatformOneSecond/4)
    590 #define DefaultAnnounceIntervalForTypeShared (mDNSPlatformOneSecond/2)
    591 #define DefaultAnnounceIntervalForTypeUnique (mDNSPlatformOneSecond/2)
    592 
    593 #define DefaultAPIntervalForRecordType(X)  ((X) & kDNSRecordTypeActiveSharedMask ? DefaultAnnounceIntervalForTypeShared : \
    594 											(X) & kDNSRecordTypeUnique           ? DefaultProbeIntervalForTypeUnique    : \
    595 											(X) & kDNSRecordTypeActiveUniqueMask ? DefaultAnnounceIntervalForTypeUnique : 0)
    596 
    597 #define TimeToAnnounceThisRecord(RR,time) ((RR)->AnnounceCount && (time) - ((RR)->LastAPTime + (RR)->ThisAPInterval) >= 0)
    598 #define TimeToSendThisRecord(RR,time) ((TimeToAnnounceThisRecord(RR,time) || (RR)->ImmedAnswer) && ResourceRecordIsValidAnswer(RR))
    599 #define TicksTTL(RR) ((mDNSs32)(RR)->resrec.rroriginalttl * mDNSPlatformOneSecond)
    600 #define RRExpireTime(RR) ((RR)->TimeRcvd + TicksTTL(RR))
    601 
    602 #define MaxUnansweredQueries 4
    603 
    604 // SameResourceRecordSignature returns true if two resources records have the same name, type, and class, and may be sent
    605 // (or were received) on the same interface (i.e. if *both* records specify an interface, then it has to match).
    606 // TTL and rdata may differ.
    607 // This is used for cache flush management:
    608 // When sending a unique record, all other records matching "SameResourceRecordSignature" must also be sent
    609 // When receiving a unique record, all old cache records matching "SameResourceRecordSignature" are flushed
    610 
    611 // SameResourceRecordNameClassInterface is functionally the same as SameResourceRecordSignature, except rrtype does not have to match
    612 
    613 #define SameResourceRecordSignature(A,B) (A)->resrec.rrtype == (B)->resrec.rrtype && SameResourceRecordNameClassInterface((A),(B))
    614 
    615 mDNSlocal mDNSBool SameResourceRecordNameClassInterface(const AuthRecord *const r1, const AuthRecord *const r2)
    616 	{
    617 	if (!r1) { LogMsg("SameResourceRecordSignature ERROR: r1 is NULL"); return(mDNSfalse); }
    618 	if (!r2) { LogMsg("SameResourceRecordSignature ERROR: r2 is NULL"); return(mDNSfalse); }
    619 	if (r1->resrec.InterfaceID &&
    620 		r2->resrec.InterfaceID &&
    621 		r1->resrec.InterfaceID != r2->resrec.InterfaceID) return(mDNSfalse);
    622 	return(mDNSBool)(
    623 		r1->resrec.rrclass  == r2->resrec.rrclass &&
    624 		r1->resrec.namehash == r2->resrec.namehash &&
    625 		SameDomainName(r1->resrec.name, r2->resrec.name));
    626 	}
    627 
    628 // PacketRRMatchesSignature behaves as SameResourceRecordSignature, except that types may differ if our
    629 // authoratative record is unique (as opposed to shared). For unique records, we are supposed to have
    630 // complete ownership of *all* types for this name, so *any* record type with the same name is a conflict.
    631 // In addition, when probing we send our questions with the wildcard type kDNSQType_ANY,
    632 // so a response of any type should match, even if it is not actually the type the client plans to use.
    633 
    634 // For now, to make it easier to avoid false conflicts, we treat SPS Proxy records like shared records,
    635 // and require the rrtypes to match for the rdata to be considered potentially conflicting
    636 mDNSlocal mDNSBool PacketRRMatchesSignature(const CacheRecord *const pktrr, const AuthRecord *const authrr)
    637 	{
    638 	if (!pktrr)  { LogMsg("PacketRRMatchesSignature ERROR: pktrr is NULL"); return(mDNSfalse); }
    639 	if (!authrr) { LogMsg("PacketRRMatchesSignature ERROR: authrr is NULL"); return(mDNSfalse); }
    640 	if (pktrr->resrec.InterfaceID &&
    641 		authrr->resrec.InterfaceID &&
    642 		pktrr->resrec.InterfaceID != authrr->resrec.InterfaceID) return(mDNSfalse);
    643 	if (!(authrr->resrec.RecordType & kDNSRecordTypeUniqueMask) || authrr->WakeUp.HMAC.l[0])
    644 		if (pktrr->resrec.rrtype != authrr->resrec.rrtype) return(mDNSfalse);
    645 	return(mDNSBool)(
    646 		pktrr->resrec.rrclass == authrr->resrec.rrclass &&
    647 		pktrr->resrec.namehash == authrr->resrec.namehash &&
    648 		SameDomainName(pktrr->resrec.name, authrr->resrec.name));
    649 	}
    650 
    651 // CacheRecord *ka is the CacheRecord from the known answer list in the query.
    652 // This is the information that the requester believes to be correct.
    653 // AuthRecord *rr is the answer we are proposing to give, if not suppressed.
    654 // This is the information that we believe to be correct.
    655 // We've already determined that we plan to give this answer on this interface
    656 // (either the record is non-specific, or it is specific to this interface)
    657 // so now we just need to check the name, type, class, rdata and TTL.
    658 mDNSlocal mDNSBool ShouldSuppressKnownAnswer(const CacheRecord *const ka, const AuthRecord *const rr)
    659 	{
    660 	// If RR signature is different, or data is different, then don't suppress our answer
    661 	if (!IdenticalResourceRecord(&ka->resrec, &rr->resrec)) return(mDNSfalse);
    662 
    663 	// If the requester's indicated TTL is less than half the real TTL,
    664 	// we need to give our answer before the requester's copy expires.
    665 	// If the requester's indicated TTL is at least half the real TTL,
    666 	// then we can suppress our answer this time.
    667 	// If the requester's indicated TTL is greater than the TTL we believe,
    668 	// then that's okay, and we don't need to do anything about it.
    669 	// (If two responders on the network are offering the same information,
    670 	// that's okay, and if they are offering the information with different TTLs,
    671 	// the one offering the lower TTL should defer to the one offering the higher TTL.)
    672 	return(mDNSBool)(ka->resrec.rroriginalttl >= rr->resrec.rroriginalttl / 2);
    673 	}
    674 
    675 mDNSlocal void SetNextAnnounceProbeTime(mDNS *const m, const AuthRecord *const rr)
    676 	{
    677 	if (rr->resrec.RecordType == kDNSRecordTypeUnique)
    678 		{
    679 		if ((rr->LastAPTime + rr->ThisAPInterval) - m->timenow > mDNSPlatformOneSecond * 10)
    680 			{
    681 			LogMsg("SetNextAnnounceProbeTime: ProbeCount %d Next in %d %s", rr->ProbeCount, (rr->LastAPTime + rr->ThisAPInterval) - m->timenow, ARDisplayString(m, rr));
    682 			LogMsg("SetNextAnnounceProbeTime: m->SuppressProbes %d m->timenow %d diff %d", m->SuppressProbes, m->timenow, m->SuppressProbes - m->timenow);
    683 			}
    684 		if (m->NextScheduledProbe - (rr->LastAPTime + rr->ThisAPInterval) >= 0)
    685 			m->NextScheduledProbe = (rr->LastAPTime + rr->ThisAPInterval);
    686 		// Some defensive code:
    687 		// If (rr->LastAPTime + rr->ThisAPInterval) happens to be far in the past, we don't want to allow
    688 		// NextScheduledProbe to be set excessively in the past, because that can cause bad things to happen.
    689 		// See: <rdar://problem/7795434> mDNS: Sometimes advertising stops working and record interval is set to zero
    690 		if (m->NextScheduledProbe - m->timenow < 0)
    691 			m->NextScheduledProbe = m->timenow;
    692 		}
    693 	else if (rr->AnnounceCount && (ResourceRecordIsValidAnswer(rr) || rr->resrec.RecordType == kDNSRecordTypeDeregistering))
    694 		{
    695 		if (m->NextScheduledResponse - (rr->LastAPTime + rr->ThisAPInterval) >= 0)
    696 			m->NextScheduledResponse = (rr->LastAPTime + rr->ThisAPInterval);
    697 		}
    698 	}
    699 
    700 mDNSlocal void InitializeLastAPTime(mDNS *const m, AuthRecord *const rr)
    701 	{
    702 	// For reverse-mapping Sleep Proxy PTR records, probe interval is one second
    703 	rr->ThisAPInterval = rr->AddressProxy.type ? mDNSPlatformOneSecond : DefaultAPIntervalForRecordType(rr->resrec.RecordType);
    704 
    705 	// * If this is a record type that's going to probe, then we use the m->SuppressProbes time.
    706 	// * Otherwise, if it's not going to probe, but m->SuppressProbes is set because we have other
    707 	//   records that are going to probe, then we delay its first announcement so that it will
    708 	//   go out synchronized with the first announcement for the other records that *are* probing.
    709 	//   This is a minor performance tweak that helps keep groups of related records synchronized together.
    710 	//   The addition of "interval / 2" is to make sure that, in the event that any of the probes are
    711 	//   delayed by a few milliseconds, this announcement does not inadvertently go out *before* the probing is complete.
    712 	//   When the probing is complete and those records begin to announce, these records will also be picked up and accelerated,
    713 	//   because they will meet the criterion of being at least half-way to their scheduled announcement time.
    714 	// * If it's not going to probe and m->SuppressProbes is not already set then we should announce immediately.
    715 
    716 	if (rr->ProbeCount)
    717 		{
    718 		// If we have no probe suppression time set, or it is in the past, set it now
    719 		if (m->SuppressProbes == 0 || m->SuppressProbes - m->timenow < 0)
    720 			{
    721 			// To allow us to aggregate probes when a group of services are registered together,
    722 			// the first probe is delayed 1/4 second. This means the common-case behaviour is:
    723 			// 1/4 second wait; probe
    724 			// 1/4 second wait; probe
    725 			// 1/4 second wait; probe
    726 			// 1/4 second wait; announce (i.e. service is normally announced exactly one second after being registered)
    727 			m->SuppressProbes = NonZeroTime(m->timenow + DefaultProbeIntervalForTypeUnique/2 + mDNSRandom(DefaultProbeIntervalForTypeUnique/2));
    728 
    729 			// If we already have a *probe* scheduled to go out sooner, then use that time to get better aggregation
    730 			if (m->SuppressProbes - m->NextScheduledProbe >= 0)
    731 				m->SuppressProbes = NonZeroTime(m->NextScheduledProbe);
    732 			if (m->SuppressProbes - m->timenow < 0)		// Make sure we don't set m->SuppressProbes excessively in the past
    733 				m->SuppressProbes = m->timenow;
    734 
    735 			// If we already have a *query* scheduled to go out sooner, then use that time to get better aggregation
    736 			if (m->SuppressProbes - m->NextScheduledQuery >= 0)
    737 				m->SuppressProbes = NonZeroTime(m->NextScheduledQuery);
    738 			if (m->SuppressProbes - m->timenow < 0)		// Make sure we don't set m->SuppressProbes excessively in the past
    739 				m->SuppressProbes = m->timenow;
    740 
    741 			// except... don't expect to be able to send before the m->SuppressSending timer fires
    742 			if (m->SuppressSending && m->SuppressProbes - m->SuppressSending < 0)
    743 				m->SuppressProbes = NonZeroTime(m->SuppressSending);
    744 
    745 			if (m->SuppressProbes - m->timenow > mDNSPlatformOneSecond * 8)
    746 				{
    747 				LogMsg("InitializeLastAPTime ERROR m->SuppressProbes %d m->NextScheduledProbe %d m->NextScheduledQuery %d m->SuppressSending %d %d",
    748 					m->SuppressProbes     - m->timenow,
    749 					m->NextScheduledProbe - m->timenow,
    750 					m->NextScheduledQuery - m->timenow,
    751 					m->SuppressSending,
    752 					m->SuppressSending    - m->timenow);
    753 				m->SuppressProbes = NonZeroTime(m->timenow + DefaultProbeIntervalForTypeUnique/2 + mDNSRandom(DefaultProbeIntervalForTypeUnique/2));
    754 				}
    755 			}
    756 		rr->LastAPTime = m->SuppressProbes - rr->ThisAPInterval;
    757 		}
    758 	else if (m->SuppressProbes && m->SuppressProbes - m->timenow >= 0)
    759 		rr->LastAPTime = m->SuppressProbes - rr->ThisAPInterval + DefaultProbeIntervalForTypeUnique * DefaultProbeCountForTypeUnique + rr->ThisAPInterval / 2;
    760 	else
    761 		rr->LastAPTime = m->timenow - rr->ThisAPInterval;
    762 
    763 	// For reverse-mapping Sleep Proxy PTR records we don't want to start probing instantly -- we
    764 	// wait one second to give the client a chance to go to sleep, and then start our ARP/NDP probing.
    765 	// After three probes one second apart with no answer, we conclude the client is now sleeping
    766 	// and we can begin broadcasting our announcements to take over ownership of that IP address.
    767 	// If we don't wait for the client to go to sleep, then when the client sees our ARP Announcements there's a risk
    768 	// (depending on the OS and networking stack it's using) that it might interpret it as a conflict and change its IP address.
    769 	if (rr->AddressProxy.type) rr->LastAPTime = m->timenow;
    770 
    771 	// Unsolicited Neighbor Advertisements (RFC 2461 Section 7.2.6) give us fast address cache updating,
    772 	// but some older IPv6 clients get confused by them, so for now we don't send them. Without Unsolicited
    773 	// Neighbor Advertisements we have to rely on Neighbor Unreachability Detection instead, which is slower.
    774 	// Given this, we'll do our best to wake for existing IPv6 connections, but we don't want to encourage
    775 	// new ones for sleeping clients, so we'll we send deletions for our SPS clients' AAAA records.
    776 	if (m->KnownBugs & mDNS_KnownBug_LimitedIPv6)
    777 		if (rr->WakeUp.HMAC.l[0] && rr->resrec.rrtype == kDNSType_AAAA)
    778 			rr->LastAPTime = m->timenow - rr->ThisAPInterval + mDNSPlatformOneSecond * 10;
    779 
    780 	// Set LastMCTime to now, to inhibit multicast responses
    781 	// (no need to send additional multicast responses when we're announcing anyway)
    782 	rr->LastMCTime      = m->timenow;
    783 	rr->LastMCInterface = mDNSInterfaceMark;
    784 
    785 	SetNextAnnounceProbeTime(m, rr);
    786 	}
    787 
    788 mDNSlocal const domainname *SetUnicastTargetToHostName(mDNS *const m, AuthRecord *rr)
    789 	{
    790 	const domainname *target;
    791 	if (rr->AutoTarget)
    792 		{
    793 		// For autotunnel services pointing at our IPv6 ULA we don't need or want a NAT mapping, but for all other
    794 		// advertised services referencing our uDNS hostname, we want NAT mappings automatically created as appropriate,
    795 		// with the port number in our advertised SRV record automatically tracking the external mapped port.
    796 		DomainAuthInfo *AuthInfo = GetAuthInfoForName_internal(m, rr->resrec.name);
    797 		if (!AuthInfo || !AuthInfo->AutoTunnel) rr->AutoTarget = Target_AutoHostAndNATMAP;
    798 		}
    799 
    800 	target = GetServiceTarget(m, rr);
    801 	if (!target || target->c[0] == 0)
    802 		{
    803 		// defer registration until we've got a target
    804 		LogInfo("SetUnicastTargetToHostName No target for %s", ARDisplayString(m, rr));
    805 		rr->state = regState_NoTarget;
    806 		return mDNSNULL;
    807 		}
    808 	else
    809 		{
    810 		LogInfo("SetUnicastTargetToHostName target %##s for resource record %s", target->c, ARDisplayString(m,rr));
    811 		return target;
    812 		}
    813 	}
    814 
    815 // Right now this only applies to mDNS (.local) services where the target host is always m->MulticastHostname
    816 // Eventually we should unify this with GetServiceTarget() in uDNS.c
    817 mDNSlocal void SetTargetToHostName(mDNS *const m, AuthRecord *const rr)
    818 	{
    819 	domainname *const target = GetRRDomainNameTarget(&rr->resrec);
    820 	const domainname *newname = &m->MulticastHostname;
    821 
    822 	if (!target) LogInfo("SetTargetToHostName: Don't know how to set the target of rrtype %s", DNSTypeName(rr->resrec.rrtype));
    823 
    824 	if (!(rr->ForceMCast || rr->ARType == AuthRecordLocalOnly || rr->ARType == AuthRecordP2P || IsLocalDomain(&rr->namestorage)))
    825 		{
    826 		const domainname *const n = SetUnicastTargetToHostName(m, rr);
    827 		if (n) newname = n;
    828 		else { target->c[0] = 0; SetNewRData(&rr->resrec, mDNSNULL, 0); return; }
    829 		}
    830 
    831 	if (target && SameDomainName(target, newname))
    832 		debugf("SetTargetToHostName: Target of %##s is already %##s", rr->resrec.name->c, target->c);
    833 
    834 	if (target && !SameDomainName(target, newname))
    835 		{
    836 		AssignDomainName(target, newname);
    837 		SetNewRData(&rr->resrec, mDNSNULL, 0);		// Update rdlength, rdestimate, rdatahash
    838 
    839 		// If we're in the middle of probing this record, we need to start again,
    840 		// because changing its rdata may change the outcome of the tie-breaker.
    841 		// (If the record type is kDNSRecordTypeUnique (unconfirmed unique) then DefaultProbeCountForRecordType is non-zero.)
    842 		rr->ProbeCount     = DefaultProbeCountForRecordType(rr->resrec.RecordType);
    843 
    844 		// If we've announced this record, we really should send a goodbye packet for the old rdata before
    845 		// changing to the new rdata. However, in practice, we only do SetTargetToHostName for unique records,
    846 		// so when we announce them we'll set the kDNSClass_UniqueRRSet and clear any stale data that way.
    847 		if (rr->RequireGoodbye && rr->resrec.RecordType == kDNSRecordTypeShared)
    848 			debugf("Have announced shared record %##s (%s) at least once: should have sent a goodbye packet before updating",
    849 				rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
    850 
    851 		rr->AnnounceCount  = InitialAnnounceCount;
    852 		rr->RequireGoodbye = mDNSfalse;
    853 		InitializeLastAPTime(m, rr);
    854 		}
    855 	}
    856 
    857 mDNSlocal void AcknowledgeRecord(mDNS *const m, AuthRecord *const rr)
    858 	{
    859 	if (rr->RecordCallback)
    860 		{
    861 		// CAUTION: MUST NOT do anything more with rr after calling rr->Callback(), because the client's callback function
    862 		// is allowed to do anything, including starting/stopping queries, registering/deregistering records, etc.
    863 		rr->Acknowledged = mDNStrue;
    864 		mDNS_DropLockBeforeCallback();		// Allow client to legally make mDNS API calls from the callback
    865 		rr->RecordCallback(m, rr, mStatus_NoError);
    866 		mDNS_ReclaimLockAfterCallback();	// Decrement mDNS_reentrancy to block mDNS API calls again
    867 		}
    868 	}
    869 
    870 mDNSexport void ActivateUnicastRegistration(mDNS *const m, AuthRecord *const rr)
    871 	{
    872 	// Make sure that we don't activate the SRV record and associated service records, if it is in
    873 	// NoTarget state. First time when a service is being instantiated, SRV record may be in NoTarget state.
    874 	// We should not activate any of the other reords (PTR, TXT) that are part of the service. When
    875 	// the target becomes available, the records will be reregistered.
    876 	if (rr->resrec.rrtype != kDNSType_SRV)
    877 		{
    878 		AuthRecord *srvRR = mDNSNULL;
    879 		if (rr->resrec.rrtype == kDNSType_PTR)
    880 			srvRR = rr->Additional1;
    881 		else if (rr->resrec.rrtype == kDNSType_TXT)
    882 			srvRR = rr->DependentOn;
    883 		if (srvRR)
    884 			{
    885 			if (srvRR->resrec.rrtype != kDNSType_SRV)
    886 				{
    887 				LogMsg("ActivateUnicastRegistration: ERROR!! Resource record %s wrong, expecting SRV type", ARDisplayString(m, srvRR));
    888 				}
    889 			else
    890 				{
    891 				LogInfo("ActivateUnicastRegistration: Found Service Record %s in state %d for %##s (%s)",
    892 					ARDisplayString(m, srvRR), srvRR->state, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
    893 				rr->state = srvRR->state;
    894 				}
    895 			}
    896 		}
    897 
    898 	if (rr->state == regState_NoTarget)
    899 		{
    900 		LogInfo("ActivateUnicastRegistration record %s in regState_NoTarget, not activating", ARDisplayString(m, rr));
    901 		return;
    902 		}
    903 	// When we wake up from sleep, we call ActivateUnicastRegistration. It is possible that just before we went to sleep,
    904 	// the service/record was being deregistered. In that case, we should not try to register again. For the cases where
    905 	// the records are deregistered due to e.g., no target for the SRV record, we would have returned from above if it
    906 	// was already in NoTarget state. If it was in the process of deregistration but did not complete fully before we went
    907 	// to sleep, then it is okay to start in Pending state as we will go back to NoTarget state if we don't have a target.
    908 	if (rr->resrec.RecordType == kDNSRecordTypeDeregistering)
    909 		{
    910 		LogInfo("ActivateUnicastRegistration: Resource record %s, current state %d, moving to DeregPending", ARDisplayString(m, rr), rr->state);
    911 		rr->state = regState_DeregPending;
    912 		}
    913 	else
    914 		{
    915 		LogInfo("ActivateUnicastRegistration: Resource record %s, current state %d, moving to Pending", ARDisplayString(m, rr), rr->state);
    916 		rr->state = regState_Pending;
    917 		}
    918 	rr->ProbeCount     = 0;
    919 	rr->AnnounceCount  = 0;
    920 	rr->ThisAPInterval = INIT_RECORD_REG_INTERVAL;
    921 	rr->LastAPTime     = m->timenow - rr->ThisAPInterval;
    922 	rr->expire         = 0;	// Forget about all the leases, start fresh
    923 	rr->uselease       = mDNStrue;
    924 	rr->updateid       = zeroID;
    925 	rr->SRVChanged     = mDNSfalse;
    926 	rr->updateError    = mStatus_NoError;
    927 	// RestartRecordGetZoneData calls this function whenever a new interface gets registered with core.
    928 	// The records might already be registered with the server and hence could have NAT state.
    929 	if (rr->NATinfo.clientContext)
    930 		{
    931 		mDNS_StopNATOperation_internal(m, &rr->NATinfo);
    932 		rr->NATinfo.clientContext = mDNSNULL;
    933 		}
    934 	if (rr->nta) { CancelGetZoneData(m, rr->nta); rr->nta = mDNSNULL; }
    935 	if (rr->tcp) { DisposeTCPConn(rr->tcp);       rr->tcp = mDNSNULL; }
    936 	if (m->NextuDNSEvent - (rr->LastAPTime + rr->ThisAPInterval) >= 0)
    937 		m->NextuDNSEvent = (rr->LastAPTime + rr->ThisAPInterval);
    938 	}
    939 
    940 // Two records qualify to be local duplicates if:
    941 // (a) the RecordTypes are the same, or
    942 // (b) one is Unique and the other Verified
    943 // (c) either is in the process of deregistering
    944 #define RecordLDT(A,B) ((A)->resrec.RecordType == (B)->resrec.RecordType || \
    945 	((A)->resrec.RecordType | (B)->resrec.RecordType) == (kDNSRecordTypeUnique | kDNSRecordTypeVerified) || \
    946 	((A)->resrec.RecordType == kDNSRecordTypeDeregistering || (B)->resrec.RecordType == kDNSRecordTypeDeregistering))
    947 
    948 #define RecordIsLocalDuplicate(A,B) \
    949 	((A)->resrec.InterfaceID == (B)->resrec.InterfaceID && RecordLDT((A),(B)) && IdenticalResourceRecord(&(A)->resrec, &(B)->resrec))
    950 
    951 mDNSlocal AuthRecord *CheckAuthIdenticalRecord(AuthHash *r, AuthRecord *rr)
    952 	{
    953 	AuthGroup *a;
    954 	AuthGroup **ag = &a;
    955 	AuthRecord **rp;
    956 	const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
    957 
    958 	a = AuthGroupForRecord(r, slot, &rr->resrec);
    959 	if (!a) return mDNSNULL;
    960 	rp = &(*ag)->members;
    961 	while (*rp)
    962 		{
    963 		if (!RecordIsLocalDuplicate(*rp, rr))
    964 			rp=&(*rp)->next;
    965 		else
    966 			{
    967 			if ((*rp)->resrec.RecordType == kDNSRecordTypeDeregistering)
    968 				{
    969 				(*rp)->AnnounceCount = 0;
    970 				rp=&(*rp)->next;
    971 				}
    972 			else return *rp;
    973 			}
    974 		}
    975 	return (mDNSNULL);
    976 	}
    977 
    978 mDNSlocal mDNSBool CheckAuthRecordConflict(AuthHash *r, AuthRecord *rr)
    979 	{
    980 	AuthGroup *a;
    981 	AuthGroup **ag = &a;
    982 	AuthRecord **rp;
    983 	const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
    984 
    985 	a = AuthGroupForRecord(r, slot, &rr->resrec);
    986 	if (!a) return mDNSfalse;
    987 	rp = &(*ag)->members;
    988 	while (*rp)
    989 		{
    990 		const AuthRecord *s1 = rr->RRSet ? rr->RRSet : rr;
    991 		const AuthRecord *s2 = (*rp)->RRSet ? (*rp)->RRSet : *rp;
    992 		if (s1 != s2 && SameResourceRecordSignature((*rp), rr) && !IdenticalSameNameRecord(&(*rp)->resrec, &rr->resrec))
    993 			return mDNStrue;
    994 		else
    995 			rp=&(*rp)->next;
    996 		}
    997 	return (mDNSfalse);
    998 	}
    999 
   1000 // checks to see if "rr" is already present
   1001 mDNSlocal AuthRecord *CheckAuthSameRecord(AuthHash *r, AuthRecord *rr)
   1002 	{
   1003 	AuthGroup *a;
   1004 	AuthGroup **ag = &a;
   1005 	AuthRecord **rp;
   1006 	const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
   1007 
   1008 	a = AuthGroupForRecord(r, slot, &rr->resrec);
   1009 	if (!a) return mDNSNULL;
   1010 	rp = &(*ag)->members;
   1011 	while (*rp)
   1012 		{
   1013 		if (*rp != rr)
   1014 			rp=&(*rp)->next;
   1015 		else
   1016 			{
   1017 			return *rp;
   1018 			}
   1019 		}
   1020 	return (mDNSNULL);
   1021 	}
   1022 
   1023 // Exported so uDNS.c can call this
   1024 mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
   1025 	{
   1026 	domainname *target = GetRRDomainNameTarget(&rr->resrec);
   1027 	AuthRecord *r;
   1028 	AuthRecord **p = &m->ResourceRecords;
   1029 	AuthRecord **d = &m->DuplicateRecords;
   1030 
   1031 	if ((mDNSs32)rr->resrec.rroriginalttl <= 0)
   1032 		{ LogMsg("mDNS_Register_internal: TTL %X should be 1 - 0x7FFFFFFF %s", rr->resrec.rroriginalttl, ARDisplayString(m, rr)); return(mStatus_BadParamErr); }
   1033 
   1034 	if (!rr->resrec.RecordType)
   1035 		{ LogMsg("mDNS_Register_internal: RecordType must be non-zero %s", ARDisplayString(m, rr)); return(mStatus_BadParamErr); }
   1036 
   1037 	if (m->ShutdownTime)
   1038 		{ LogMsg("mDNS_Register_internal: Shutting down, can't register %s", ARDisplayString(m, rr)); return(mStatus_ServiceNotRunning); }
   1039 
   1040 	if (m->DivertMulticastAdvertisements && !AuthRecord_uDNS(rr))
   1041 		{
   1042 		mDNSInterfaceID previousID = rr->resrec.InterfaceID;
   1043 		if (rr->resrec.InterfaceID == mDNSInterface_Any || rr->resrec.InterfaceID == mDNSInterface_P2P)
   1044 			{
   1045 			rr->resrec.InterfaceID = mDNSInterface_LocalOnly;
   1046 			rr->ARType = AuthRecordLocalOnly;
   1047 			}
   1048 		if (rr->resrec.InterfaceID != mDNSInterface_LocalOnly)
   1049 			{
   1050 			NetworkInterfaceInfo *intf = FirstInterfaceForID(m, rr->resrec.InterfaceID);
   1051 			if (intf && !intf->Advertise){ rr->resrec.InterfaceID = mDNSInterface_LocalOnly; rr->ARType = AuthRecordLocalOnly; }
   1052 			}
   1053 		if (rr->resrec.InterfaceID != previousID)
   1054 			LogInfo("mDNS_Register_internal: Diverting record to local-only %s", ARDisplayString(m, rr));
   1055 		}
   1056 
   1057 	if (RRLocalOnly(rr))
   1058 		{
   1059 		if (CheckAuthSameRecord(&m->rrauth, rr))
   1060 			{
   1061 			LogMsg("mDNS_Register_internal: ERROR!! Tried to register LocalOnly AuthRecord %p %##s (%s) that's already in the list",
   1062 				rr, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
   1063 			return(mStatus_AlreadyRegistered);
   1064 			}
   1065 		}
   1066 	else
   1067 		{
   1068 		while (*p && *p != rr) p=&(*p)->next;
   1069 		if (*p)
   1070 			{
   1071 			LogMsg("mDNS_Register_internal: ERROR!! Tried to register AuthRecord %p %##s (%s) that's already in the list",
   1072 				rr, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
   1073 			return(mStatus_AlreadyRegistered);
   1074 			}
   1075 		}
   1076 
   1077 	while (*d && *d != rr) d=&(*d)->next;
   1078 	if (*d)
   1079 		{
   1080 		LogMsg("mDNS_Register_internal: ERROR!! Tried to register AuthRecord %p %##s (%s) that's already in the Duplicate list",
   1081 				rr, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
   1082 		return(mStatus_AlreadyRegistered);
   1083 		}
   1084 
   1085 	if (rr->DependentOn)
   1086 		{
   1087 		if (rr->resrec.RecordType == kDNSRecordTypeUnique)
   1088 			rr->resrec.RecordType =  kDNSRecordTypeVerified;
   1089 		else
   1090 			{
   1091 			LogMsg("mDNS_Register_internal: ERROR! %##s (%s): rr->DependentOn && RecordType != kDNSRecordTypeUnique",
   1092 				rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
   1093 			return(mStatus_Invalid);
   1094 			}
   1095 		if (!(rr->DependentOn->resrec.RecordType & (kDNSRecordTypeUnique | kDNSRecordTypeVerified | kDNSRecordTypeKnownUnique)))
   1096 			{
   1097 			LogMsg("mDNS_Register_internal: ERROR! %##s (%s): rr->DependentOn->RecordType bad type %X",
   1098 				rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype), rr->DependentOn->resrec.RecordType);
   1099 			return(mStatus_Invalid);
   1100 			}
   1101 		}
   1102 
   1103 	// If this resource record is referencing a specific interface, make sure it exists.
   1104 	// Skip checks for LocalOnly and P2P as they are not valid InterfaceIDs. Also, for scoped
   1105 	// entries in /etc/hosts skip that check as that interface may not be valid at this time.
   1106 	if (rr->resrec.InterfaceID && rr->ARType != AuthRecordLocalOnly && rr->ARType != AuthRecordP2P)
   1107 		{
   1108 		NetworkInterfaceInfo *intf = FirstInterfaceForID(m, rr->resrec.InterfaceID);
   1109 		if (!intf)
   1110 			{
   1111 			debugf("mDNS_Register_internal: Bogus InterfaceID %p in resource record", rr->resrec.InterfaceID);
   1112 			return(mStatus_BadReferenceErr);
   1113 			}
   1114 		}
   1115 
   1116 	rr->next = mDNSNULL;
   1117 
   1118 	// Field Group 1: The actual information pertaining to this resource record
   1119 	// Set up by client prior to call
   1120 
   1121 	// Field Group 2: Persistent metadata for Authoritative Records
   1122 //	rr->Additional1       = set to mDNSNULL  in mDNS_SetupResourceRecord; may be overridden by client
   1123 //	rr->Additional2       = set to mDNSNULL  in mDNS_SetupResourceRecord; may be overridden by client
   1124 //	rr->DependentOn       = set to mDNSNULL  in mDNS_SetupResourceRecord; may be overridden by client
   1125 //	rr->RRSet             = set to mDNSNULL  in mDNS_SetupResourceRecord; may be overridden by client
   1126 //	rr->Callback          = already set      in mDNS_SetupResourceRecord
   1127 //	rr->Context           = already set      in mDNS_SetupResourceRecord
   1128 //	rr->RecordType        = already set      in mDNS_SetupResourceRecord
   1129 //	rr->HostTarget        = set to mDNSfalse in mDNS_SetupResourceRecord; may be overridden by client
   1130 //	rr->AllowRemoteQuery  = set to mDNSfalse in mDNS_SetupResourceRecord; may be overridden by client
   1131 	// Make sure target is not uninitialized data, or we may crash writing debugging log messages
   1132 	if (rr->AutoTarget && target) target->c[0] = 0;
   1133 
   1134 	// Field Group 3: Transient state for Authoritative Records
   1135 	rr->Acknowledged      = mDNSfalse;
   1136 	rr->ProbeCount        = DefaultProbeCountForRecordType(rr->resrec.RecordType);
   1137 	rr->AnnounceCount     = InitialAnnounceCount;
   1138 	rr->RequireGoodbye    = mDNSfalse;
   1139 	rr->AnsweredLocalQ    = mDNSfalse;
   1140 	rr->IncludeInProbe    = mDNSfalse;
   1141 	rr->ImmedUnicast      = mDNSfalse;
   1142 	rr->SendNSECNow       = mDNSNULL;
   1143 	rr->ImmedAnswer       = mDNSNULL;
   1144 	rr->ImmedAdditional   = mDNSNULL;
   1145 	rr->SendRNow          = mDNSNULL;
   1146 	rr->v4Requester       = zerov4Addr;
   1147 	rr->v6Requester       = zerov6Addr;
   1148 	rr->NextResponse      = mDNSNULL;
   1149 	rr->NR_AnswerTo       = mDNSNULL;
   1150 	rr->NR_AdditionalTo   = mDNSNULL;
   1151 	if (!rr->AutoTarget) InitializeLastAPTime(m, rr);
   1152 //	rr->LastAPTime        = Set for us in InitializeLastAPTime()
   1153 //	rr->LastMCTime        = Set for us in InitializeLastAPTime()
   1154 //	rr->LastMCInterface   = Set for us in InitializeLastAPTime()
   1155 	rr->NewRData          = mDNSNULL;
   1156 	rr->newrdlength       = 0;
   1157 	rr->UpdateCallback    = mDNSNULL;
   1158 	rr->UpdateCredits     = kMaxUpdateCredits;
   1159 	rr->NextUpdateCredit  = 0;
   1160 	rr->UpdateBlocked     = 0;
   1161 
   1162 	// For records we're holding as proxy (except reverse-mapping PTR records) two announcements is sufficient
   1163 	if (rr->WakeUp.HMAC.l[0] && !rr->AddressProxy.type) rr->AnnounceCount = 2;
   1164 
   1165 	// Field Group 4: Transient uDNS state for Authoritative Records
   1166 	rr->state             = regState_Zero;
   1167 	rr->uselease          = 0;
   1168 	rr->expire            = 0;
   1169 	rr->Private           = 0;
   1170 	rr->updateid          = zeroID;
   1171 	rr->zone              = rr->resrec.name;
   1172 	rr->nta               = mDNSNULL;
   1173 	rr->tcp               = mDNSNULL;
   1174 	rr->OrigRData         = 0;
   1175 	rr->OrigRDLen         = 0;
   1176 	rr->InFlightRData     = 0;
   1177 	rr->InFlightRDLen     = 0;
   1178 	rr->QueuedRData       = 0;
   1179 	rr->QueuedRDLen       = 0;
   1180 	//mDNSPlatformMemZero(&rr->NATinfo, sizeof(rr->NATinfo));
   1181 	// We should be recording the actual internal port for this service record here. Once we initiate our NAT mapping
   1182 	// request we'll subsequently overwrite srv.port with the allocated external NAT port -- potentially multiple
   1183 	// times with different values if the external NAT port changes during the lifetime of the service registration.
   1184 	//if (rr->resrec.rrtype == kDNSType_SRV) rr->NATinfo.IntPort = rr->resrec.rdata->u.srv.port;
   1185 
   1186 //	rr->resrec.interface         = already set in mDNS_SetupResourceRecord
   1187 //	rr->resrec.name->c           = MUST be set by client
   1188 //	rr->resrec.rrtype            = already set in mDNS_SetupResourceRecord
   1189 //	rr->resrec.rrclass           = already set in mDNS_SetupResourceRecord
   1190 //	rr->resrec.rroriginalttl     = already set in mDNS_SetupResourceRecord
   1191 //	rr->resrec.rdata             = MUST be set by client, unless record type is CNAME or PTR and rr->HostTarget is set
   1192 
   1193 	// BIND named (name daemon) doesn't allow TXT records with zero-length rdata. This is strictly speaking correct,
   1194 	// since RFC 1035 specifies a TXT record as "One or more <character-string>s", not "Zero or more <character-string>s".
   1195 	// Since some legacy apps try to create zero-length TXT records, we'll silently correct it here.
   1196 	if (rr->resrec.rrtype == kDNSType_TXT && rr->resrec.rdlength == 0) { rr->resrec.rdlength = 1; rr->resrec.rdata->u.txt.c[0] = 0; }
   1197 
   1198 	if (rr->AutoTarget)
   1199 		{
   1200 		SetTargetToHostName(m, rr);	// Also sets rdlength and rdestimate for us, and calls InitializeLastAPTime();
   1201 #ifndef UNICAST_DISABLED
   1202 		// If we have no target record yet, SetTargetToHostName will set rr->state == regState_NoTarget
   1203 		// In this case we leave the record half-formed in the list, and later we'll remove it from the list and re-add it properly.
   1204 		if (rr->state == regState_NoTarget)
   1205 			{
   1206 			// Initialize the target so that we don't crash while logging etc.
   1207 			domainname *tar = GetRRDomainNameTarget(&rr->resrec);
   1208 			if (tar) tar->c[0] = 0;
   1209 			LogInfo("mDNS_Register_internal: record %s in NoTarget state", ARDisplayString(m, rr));
   1210 			}
   1211 #endif
   1212 		}
   1213 	else
   1214 		{
   1215 		rr->resrec.rdlength   = GetRDLength(&rr->resrec, mDNSfalse);
   1216 		rr->resrec.rdestimate = GetRDLength(&rr->resrec, mDNStrue);
   1217 		}
   1218 
   1219 	if (!ValidateDomainName(rr->resrec.name))
   1220 		{ LogMsg("Attempt to register record with invalid name: %s", ARDisplayString(m, rr)); return(mStatus_Invalid); }
   1221 
   1222 	// Don't do this until *after* we've set rr->resrec.rdlength
   1223 	if (!ValidateRData(rr->resrec.rrtype, rr->resrec.rdlength, rr->resrec.rdata))
   1224 		{ LogMsg("Attempt to register record with invalid rdata: %s", ARDisplayString(m, rr)); return(mStatus_Invalid); }
   1225 
   1226 	rr->resrec.namehash   = DomainNameHashValue(rr->resrec.name);
   1227 	rr->resrec.rdatahash  = target ? DomainNameHashValue(target) : RDataHashValue(&rr->resrec);
   1228 
   1229 	if (RRLocalOnly(rr))
   1230 		{
   1231 		// If this is supposed to be unique, make sure we don't have any name conflicts.
   1232 		// If we found a conflict, we may still want to insert the record in the list but mark it appropriately
   1233 		// (kDNSRecordTypeDeregistering) so that we deliver RMV events to the application. But this causes more
   1234 		// complications and not clear whether there are any benefits. See rdar:9304275 for details.
   1235 		// Hence, just bail out.
   1236 		if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
   1237 			{
   1238 			if (CheckAuthRecordConflict(&m->rrauth, rr))
   1239 				{
   1240 				LogInfo("mDNS_Register_internal: Name conflict %s (%p), InterfaceID %p", ARDisplayString(m, rr), rr, rr->resrec.InterfaceID);
   1241 				return mStatus_NameConflict;
   1242 				}
   1243 			}
   1244 		}
   1245 
   1246 	// For uDNS records, we don't support duplicate checks at this time.
   1247 #ifndef UNICAST_DISABLED
   1248 	if (AuthRecord_uDNS(rr))
   1249 		{
   1250 		if (!m->NewLocalRecords) m->NewLocalRecords = rr;
   1251 		// When we called SetTargetToHostName, it may have caused mDNS_Register_internal to be re-entered, appending new
   1252 		// records to the list, so we now need to update p to advance to the new end to the list before appending our new record.
   1253 		// Note that for AutoTunnel this should never happen, but this check makes the code future-proof.
   1254 		while (*p) p=&(*p)->next;
   1255 		*p = rr;
   1256 		if (rr->resrec.RecordType == kDNSRecordTypeUnique) rr->resrec.RecordType = kDNSRecordTypeVerified;
   1257 		rr->ProbeCount    = 0;
   1258 		rr->AnnounceCount = 0;
   1259 		if (rr->state != regState_NoTarget) ActivateUnicastRegistration(m, rr);
   1260 		return(mStatus_NoError);			// <--- Note: For unicast records, code currently bails out at this point
   1261 		}
   1262 #endif
   1263 
   1264 	// Now that we've finished building our new record, make sure it's not identical to one we already have
   1265 	if (RRLocalOnly(rr))
   1266 		{
   1267 		rr->ProbeCount    = 0;
   1268 		rr->AnnounceCount = 0;
   1269 		r = CheckAuthIdenticalRecord(&m->rrauth, rr);
   1270 		}
   1271 	else
   1272 		{
   1273 		for (r = m->ResourceRecords; r; r=r->next)
   1274 			if (RecordIsLocalDuplicate(r, rr))
   1275 				{
   1276 				if (r->resrec.RecordType == kDNSRecordTypeDeregistering) r->AnnounceCount = 0;
   1277 				else break;
   1278 				}
   1279 		}
   1280 
   1281 	if (r)
   1282 		{
   1283 		debugf("mDNS_Register_internal:Adding to duplicate list %s", ARDisplayString(m,rr));
   1284 		*d = rr;
   1285 		// If the previous copy of this record is already verified unique,
   1286 		// then indicate that we should move this record promptly to kDNSRecordTypeUnique state.
   1287 		// Setting ProbeCount to zero will cause SendQueries() to advance this record to
   1288 		// kDNSRecordTypeVerified state and call the client callback at the next appropriate time.
   1289 		if (rr->resrec.RecordType == kDNSRecordTypeUnique && r->resrec.RecordType == kDNSRecordTypeVerified)
   1290 			rr->ProbeCount = 0;
   1291 		}
   1292 	else
   1293 		{
   1294 		debugf("mDNS_Register_internal: Adding to active record list %s", ARDisplayString(m,rr));
   1295 		if (RRLocalOnly(rr))
   1296 			{
   1297 			AuthGroup *ag;
   1298 			ag = InsertAuthRecord(m, &m->rrauth, rr);
   1299 			if (ag && !ag->NewLocalOnlyRecords) {
   1300 				m->NewLocalOnlyRecords = mDNStrue;
   1301 				ag->NewLocalOnlyRecords = rr;
   1302 			}
   1303 			// No probing for LocalOnly records, Acknowledge them right away
   1304 			if (rr->resrec.RecordType == kDNSRecordTypeUnique) rr->resrec.RecordType = kDNSRecordTypeVerified;
   1305 			AcknowledgeRecord(m, rr);
   1306 			return(mStatus_NoError);
   1307 			}
   1308 		else
   1309 			{
   1310 			if (!m->NewLocalRecords) m->NewLocalRecords = rr;
   1311 			*p = rr;
   1312 			}
   1313 		}
   1314 
   1315 	if (!AuthRecord_uDNS(rr))	// This check is superfluous, given that for unicast records we (currently) bail out above
   1316 		{
   1317 		// For records that are not going to probe, acknowledge them right away
   1318 		if (rr->resrec.RecordType != kDNSRecordTypeUnique && rr->resrec.RecordType != kDNSRecordTypeDeregistering)
   1319 			AcknowledgeRecord(m, rr);
   1320 
   1321 		// Adding a record may affect whether or not we should sleep
   1322 		mDNS_UpdateAllowSleep(m);
   1323 		}
   1324 
   1325 	return(mStatus_NoError);
   1326 	}
   1327 
   1328 mDNSlocal void RecordProbeFailure(mDNS *const m, const AuthRecord *const rr)
   1329 	{
   1330 	m->ProbeFailTime = m->timenow;
   1331 	m->NumFailedProbes++;
   1332 	// If we've had fifteen or more probe failures, rate-limit to one every five seconds.
   1333 	// If a bunch of hosts have all been configured with the same name, then they'll all
   1334 	// conflict and run through the same series of names: name-2, name-3, name-4, etc.,
   1335 	// up to name-10. After that they'll start adding random increments in the range 1-100,
   1336 	// so they're more likely to branch out in the available namespace and settle on a set of
   1337 	// unique names quickly. If after five more tries the host is still conflicting, then we
   1338 	// may have a serious problem, so we start rate-limiting so we don't melt down the network.
   1339 	if (m->NumFailedProbes >= 15)
   1340 		{
   1341 		m->SuppressProbes = NonZeroTime(m->timenow + mDNSPlatformOneSecond * 5);
   1342 		LogMsg("Excessive name conflicts (%lu) for %##s (%s); rate limiting in effect",
   1343 			m->NumFailedProbes, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
   1344 		}
   1345 	}
   1346 
   1347 mDNSlocal void CompleteRDataUpdate(mDNS *const m, AuthRecord *const rr)
   1348 	{
   1349 	RData *OldRData = rr->resrec.rdata;
   1350 	mDNSu16 OldRDLen = rr->resrec.rdlength;
   1351 	SetNewRData(&rr->resrec, rr->NewRData, rr->newrdlength);	// Update our rdata
   1352 	rr->NewRData = mDNSNULL;									// Clear the NewRData pointer ...
   1353 	if (rr->UpdateCallback)
   1354 		rr->UpdateCallback(m, rr, OldRData, OldRDLen);			// ... and let the client know
   1355 	}
   1356 
   1357 // Note: mDNS_Deregister_internal can call a user callback, which may change the record list and/or question list.
   1358 // Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
   1359 // Exported so uDNS.c can call this
   1360 mDNSexport mStatus mDNS_Deregister_internal(mDNS *const m, AuthRecord *const rr, mDNS_Dereg_type drt)
   1361 	{
   1362 	AuthRecord *r2;
   1363 	mDNSu8 RecordType = rr->resrec.RecordType;
   1364 	AuthRecord **p = &m->ResourceRecords;	// Find this record in our list of active records
   1365 	mDNSBool dupList = mDNSfalse;
   1366 
   1367 	if (RRLocalOnly(rr))
   1368 		{
   1369 		AuthGroup *a;
   1370 		AuthGroup **ag = &a;
   1371 		AuthRecord **rp;
   1372 		const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
   1373 
   1374 		a = AuthGroupForRecord(&m->rrauth, slot, &rr->resrec);
   1375 		if (!a) return mDNSfalse;
   1376 		rp = &(*ag)->members;
   1377 		while (*rp && *rp != rr) rp=&(*rp)->next;
   1378 		p = rp;
   1379 		}
   1380 	else
   1381 		{
   1382 		while (*p && *p != rr) p=&(*p)->next;
   1383 		}
   1384 
   1385 	if (*p)
   1386 		{
   1387 		// We found our record on the main list. See if there are any duplicates that need special handling.
   1388 		if (drt == mDNS_Dereg_conflict)		// If this was a conflict, see that all duplicates get the same treatment
   1389 			{
   1390 			// Scan for duplicates of rr, and mark them for deregistration at the end of this routine, after we've finished
   1391 			// deregistering rr. We need to do this scan *before* we give the client the chance to free and reuse the rr memory.
   1392 			for (r2 = m->DuplicateRecords; r2; r2=r2->next) if (RecordIsLocalDuplicate(r2, rr)) r2->ProbeCount = 0xFF;
   1393 			}
   1394 		else
   1395 			{
   1396 			// Before we delete the record (and potentially send a goodbye packet)
   1397 			// first see if we have a record on the duplicate list ready to take over from it.
   1398 			AuthRecord **d = &m->DuplicateRecords;
   1399 			while (*d && !RecordIsLocalDuplicate(*d, rr)) d=&(*d)->next;
   1400 			if (*d)
   1401 				{
   1402 				AuthRecord *dup = *d;
   1403 				debugf("mDNS_Register_internal: Duplicate record %p taking over from %p %##s (%s)",
   1404 					dup, rr, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
   1405 				*d        = dup->next;		// Cut replacement record from DuplicateRecords list
   1406 				if (RRLocalOnly(rr))
   1407 					{
   1408 					dup->next = mDNSNULL;
   1409 					if (!InsertAuthRecord(m, &m->rrauth, dup)) LogMsg("mDNS_Deregister_internal: ERROR!! cannot insert %s", ARDisplayString(m, dup));
   1410 					}
   1411 				else
   1412 					{
   1413 					dup->next = rr->next;		// And then...
   1414 					rr->next  = dup;			// ... splice it in right after the record we're about to delete
   1415 					}
   1416 				dup->resrec.RecordType        = rr->resrec.RecordType;
   1417 				dup->ProbeCount      = rr->ProbeCount;
   1418 				dup->AnnounceCount   = rr->AnnounceCount;
   1419 				dup->RequireGoodbye  = rr->RequireGoodbye;
   1420 				dup->AnsweredLocalQ  = rr->AnsweredLocalQ;
   1421 				dup->ImmedAnswer     = rr->ImmedAnswer;
   1422 				dup->ImmedUnicast    = rr->ImmedUnicast;
   1423 				dup->ImmedAdditional = rr->ImmedAdditional;
   1424 				dup->v4Requester     = rr->v4Requester;
   1425 				dup->v6Requester     = rr->v6Requester;
   1426 				dup->ThisAPInterval  = rr->ThisAPInterval;
   1427 				dup->LastAPTime      = rr->LastAPTime;
   1428 				dup->LastMCTime      = rr->LastMCTime;
   1429 				dup->LastMCInterface = rr->LastMCInterface;
   1430 				dup->Private         = rr->Private;
   1431 				dup->state           = rr->state;
   1432 				rr->RequireGoodbye = mDNSfalse;
   1433 				rr->AnsweredLocalQ = mDNSfalse;
   1434 				}
   1435 			}
   1436 		}
   1437 	else
   1438 		{
   1439 		// We didn't find our record on the main list; try the DuplicateRecords list instead.
   1440 		p = &m->DuplicateRecords;
   1441 		while (*p && *p != rr) p=&(*p)->next;
   1442 		// If we found our record on the duplicate list, then make sure we don't send a goodbye for it
   1443 		if (*p) { rr->RequireGoodbye = mDNSfalse; dupList = mDNStrue; }
   1444 		if (*p) debugf("mDNS_Deregister_internal: Deleting DuplicateRecord %p %##s (%s)",
   1445 			rr, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
   1446 		}
   1447 
   1448 	if (!*p)
   1449 		{
   1450 		// No need to log an error message if we already know this is a potentially repeated deregistration
   1451 		if (drt != mDNS_Dereg_repeat)
   1452 			LogMsg("mDNS_Deregister_internal: Record %p not found in list %s", rr, ARDisplayString(m,rr));
   1453 		return(mStatus_BadReferenceErr);
   1454 		}
   1455 
   1456 	// If this is a shared record and we've announced it at least once,
   1457 	// we need to retract that announcement before we delete the record
   1458 
   1459 	// If this is a record (including mDNSInterface_LocalOnly records) for which we've given local-only answers then
   1460 	// it's tempting to just do "AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse)" here, but that would not not be safe.
   1461 	// The AnswerAllLocalQuestionsWithLocalAuthRecord routine walks the question list invoking client callbacks, using the "m->CurrentQuestion"
   1462 	// mechanism to cope with the client callback modifying the question list while that's happening.
   1463 	// However, mDNS_Deregister could have been called from a client callback (e.g. from the domain enumeration callback FoundDomain)
   1464 	// which means that the "m->CurrentQuestion" mechanism is already in use to protect that list, so we can't use it twice.
   1465 	// More generally, if we invoke callbacks from within a client callback, then those callbacks could deregister other
   1466 	// records, thereby invoking yet more callbacks, without limit.
   1467 	// The solution is to defer delivering the "Remove" events until mDNS_Execute time, just like we do for sending
   1468 	// actual goodbye packets.
   1469 
   1470 #ifndef UNICAST_DISABLED
   1471 	if (AuthRecord_uDNS(rr))
   1472 		{
   1473 		if (rr->RequireGoodbye)
   1474 			{
   1475 			if (rr->tcp) { DisposeTCPConn(rr->tcp); rr->tcp = mDNSNULL; }
   1476 			rr->resrec.RecordType    = kDNSRecordTypeDeregistering;
   1477 			m->LocalRemoveEvents     = mDNStrue;
   1478 			uDNS_DeregisterRecord(m, rr);
   1479 			// At this point unconditionally we bail out
   1480 			// Either uDNS_DeregisterRecord will have completed synchronously, and called CompleteDeregistration,
   1481 			// which calls us back here with RequireGoodbye set to false, or it will have initiated the deregistration
   1482 			// process and will complete asynchronously. Either way we don't need to do anything more here.
   1483 			return(mStatus_NoError);
   1484 			}
   1485 		// Sometimes the records don't complete proper deregistration i.e., don't wait for a response
   1486 		// from the server. In that case, if the records have been part of a group update, clear the
   1487 		// state here. Some recors e.g., AutoTunnel gets reused without ever being completely initialized
   1488 		rr->updateid = zeroID;
   1489 
   1490 		// We defer cleaning up NAT state only after sending goodbyes. This is important because
   1491 		// RecordRegistrationGotZoneData guards against creating NAT state if clientContext is non-NULL.
   1492 		// This happens today when we turn on/off interface where we get multiple network transitions
   1493 		// and RestartRecordGetZoneData triggers re-registration of the resource records even though
   1494 		// they may be in Registered state which causes NAT information to be setup multiple times. Defering
   1495 		// the cleanup here keeps clientContext non-NULL and hence prevents that. Note that cleaning up
   1496 		// NAT state here takes care of the case where we did not send goodbyes at all.
   1497 		if (rr->NATinfo.clientContext)
   1498 			{
   1499 			mDNS_StopNATOperation_internal(m, &rr->NATinfo);
   1500 			rr->NATinfo.clientContext = mDNSNULL;
   1501 			}
   1502 		if (rr->nta) { CancelGetZoneData(m, rr->nta); rr->nta = mDNSNULL; }
   1503 		if (rr->tcp) { DisposeTCPConn(rr->tcp);       rr->tcp = mDNSNULL; }
   1504 		}
   1505 #endif // UNICAST_DISABLED
   1506 
   1507 	if      (RecordType == kDNSRecordTypeUnregistered)
   1508 		LogMsg("mDNS_Deregister_internal: %s already marked kDNSRecordTypeUnregistered", ARDisplayString(m, rr));
   1509 	else if (RecordType == kDNSRecordTypeDeregistering)
   1510 		{
   1511 		LogMsg("mDNS_Deregister_internal: %s already marked kDNSRecordTypeDeregistering", ARDisplayString(m, rr));
   1512 		return(mStatus_BadReferenceErr);
   1513 		}
   1514 
   1515 	// <rdar://problem/7457925> Local-only questions don't get remove events for unique records
   1516 	// We may want to consider changing this code so that we generate local-only question "rmv"
   1517 	// events (and maybe goodbye packets too) for unique records as well as for shared records
   1518 	// Note: If we change the logic for this "if" statement, need to ensure that the code in
   1519 	// CompleteDeregistration() sets the appropriate state variables to gaurantee that "else"
   1520 	// clause will execute here and the record will be cut from the list.
   1521 	if (rr->WakeUp.HMAC.l[0] ||
   1522 		(RecordType == kDNSRecordTypeShared && (rr->RequireGoodbye || rr->AnsweredLocalQ)))
   1523 		{
   1524 		verbosedebugf("mDNS_Deregister_internal: Starting deregistration for %s", ARDisplayString(m, rr));
   1525 		rr->resrec.RecordType    = kDNSRecordTypeDeregistering;
   1526 		rr->resrec.rroriginalttl = 0;
   1527 		rr->AnnounceCount        = rr->WakeUp.HMAC.l[0] ? WakeupCount : (drt == mDNS_Dereg_rapid) ? 1 : GoodbyeCount;
   1528 		rr->ThisAPInterval       = mDNSPlatformOneSecond * 2;
   1529 		rr->LastAPTime           = m->timenow - rr->ThisAPInterval;
   1530 		m->LocalRemoveEvents     = mDNStrue;
   1531 		if (m->NextScheduledResponse - (m->timenow + mDNSPlatformOneSecond/10) >= 0)
   1532 			m->NextScheduledResponse = (m->timenow + mDNSPlatformOneSecond/10);
   1533 		}
   1534 	else
   1535 		{
   1536 		if (!dupList && RRLocalOnly(rr))
   1537 			{
   1538 			AuthGroup *ag = RemoveAuthRecord(m, &m->rrauth, rr);
   1539 			if (ag->NewLocalOnlyRecords == rr) ag->NewLocalOnlyRecords = rr->next;
   1540 			}
   1541 		else
   1542 			{
   1543 			*p = rr->next;					// Cut this record from the list
   1544 			if (m->NewLocalRecords == rr) m->NewLocalRecords = rr->next;
   1545 			}
   1546 		// If someone is about to look at this, bump the pointer forward
   1547 		if (m->CurrentRecord   == rr) m->CurrentRecord   = rr->next;
   1548 		rr->next = mDNSNULL;
   1549 
   1550 		// Should we generate local remove events here?
   1551 		// i.e. something like:
   1552 		// if (rr->AnsweredLocalQ) { AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse); rr->AnsweredLocalQ = mDNSfalse; }
   1553 
   1554 		verbosedebugf("mDNS_Deregister_internal: Deleting record for %s", ARDisplayString(m, rr));
   1555 		rr->resrec.RecordType = kDNSRecordTypeUnregistered;
   1556 
   1557 		if ((drt == mDNS_Dereg_conflict || drt == mDNS_Dereg_repeat) && RecordType == kDNSRecordTypeShared)
   1558 			debugf("mDNS_Deregister_internal: Cannot have a conflict on a shared record! %##s (%s)",
   1559 				rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
   1560 
   1561 		// If we have an update queued up which never executed, give the client a chance to free that memory
   1562 		if (rr->NewRData) CompleteRDataUpdate(m, rr);	// Update our rdata, clear the NewRData pointer, and return memory to the client
   1563 
   1564 
   1565 		// CAUTION: MUST NOT do anything more with rr after calling rr->Callback(), because the client's callback function
   1566 		// is allowed to do anything, including starting/stopping queries, registering/deregistering records, etc.
   1567 		// In this case the likely client action to the mStatus_MemFree message is to free the memory,
   1568 		// so any attempt to touch rr after this is likely to lead to a crash.
   1569 		if (drt != mDNS_Dereg_conflict)
   1570 			{
   1571 			mDNS_DropLockBeforeCallback();		// Allow client to legally make mDNS API calls from the callback
   1572 			LogInfo("mDNS_Deregister_internal: mStatus_MemFree for %s", ARDisplayString(m, rr));
   1573 			if (rr->RecordCallback)
   1574 				rr->RecordCallback(m, rr, mStatus_MemFree);			// MUST NOT touch rr after this
   1575 			mDNS_ReclaimLockAfterCallback();	// Decrement mDNS_reentrancy to block mDNS API calls again
   1576 			}
   1577 		else
   1578 			{
   1579 			RecordProbeFailure(m, rr);
   1580 			mDNS_DropLockBeforeCallback();		// Allow client to legally make mDNS API calls from the callback
   1581 			if (rr->RecordCallback)
   1582 				rr->RecordCallback(m, rr, mStatus_NameConflict);	// MUST NOT touch rr after this
   1583 			mDNS_ReclaimLockAfterCallback();	// Decrement mDNS_reentrancy to block mDNS API calls again
   1584 			// Now that we've finished deregistering rr, check our DuplicateRecords list for any that we marked previously.
   1585 			// Note that with all the client callbacks going on, by the time we get here all the
   1586 			// records we marked may have been explicitly deregistered by the client anyway.
   1587 			r2 = m->DuplicateRecords;
   1588 			while (r2)
   1589 				{
   1590 				if (r2->ProbeCount != 0xFF) r2 = r2->next;
   1591 				else { mDNS_Deregister_internal(m, r2, mDNS_Dereg_conflict); r2 = m->DuplicateRecords; }
   1592 				}
   1593 			}
   1594 		}
   1595 	mDNS_UpdateAllowSleep(m);
   1596 	return(mStatus_NoError);
   1597 	}
   1598 
   1599 // ***************************************************************************
   1600 #if COMPILER_LIKES_PRAGMA_MARK
   1601 #pragma mark -
   1602 #pragma mark - Packet Sending Functions
   1603 #endif
   1604 
   1605 mDNSlocal void AddRecordToResponseList(AuthRecord ***nrpp, AuthRecord *rr, AuthRecord *add)
   1606 	{
   1607 	if (rr->NextResponse == mDNSNULL && *nrpp != &rr->NextResponse)
   1608 		{
   1609 		**nrpp = rr;
   1610 		// NR_AdditionalTo must point to a record with NR_AnswerTo set (and not NR_AdditionalTo)
   1611 		// If 'add' does not meet this requirement, then follow its NR_AdditionalTo pointer to a record that does
   1612 		// The referenced record will definitely be acceptable (by recursive application of this rule)
   1613 		if (add && add->NR_AdditionalTo) add = add->NR_AdditionalTo;
   1614 		rr->NR_AdditionalTo = add;
   1615 		*nrpp = &rr->NextResponse;
   1616 		}
   1617 	debugf("AddRecordToResponseList: %##s (%s) already in list", rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
   1618 	}
   1619 
   1620 mDNSlocal void AddAdditionalsToResponseList(mDNS *const m, AuthRecord *ResponseRecords, AuthRecord ***nrpp, const mDNSInterfaceID InterfaceID)
   1621 	{
   1622 	AuthRecord  *rr, *rr2;
   1623 	for (rr=ResponseRecords; rr; rr=rr->NextResponse)			// For each record we plan to put
   1624 		{
   1625 		// (Note: This is an "if", not a "while". If we add a record, we'll find it again
   1626 		// later in the "for" loop, and we will follow further "additional" links then.)
   1627 		if (rr->Additional1 && ResourceRecordIsValidInterfaceAnswer(rr->Additional1, InterfaceID))
   1628 			AddRecordToResponseList(nrpp, rr->Additional1, rr);
   1629 
   1630 		if (rr->Additional2 && ResourceRecordIsValidInterfaceAnswer(rr->Additional2, InterfaceID))
   1631 			AddRecordToResponseList(nrpp, rr->Additional2, rr);
   1632 
   1633 		// For SRV records, automatically add the Address record(s) for the target host
   1634 		if (rr->resrec.rrtype == kDNSType_SRV)
   1635 			{
   1636 			for (rr2=m->ResourceRecords; rr2; rr2=rr2->next)					// Scan list of resource records
   1637 				if (RRTypeIsAddressType(rr2->resrec.rrtype) &&					// For all address records (A/AAAA) ...
   1638 					ResourceRecordIsValidInterfaceAnswer(rr2, InterfaceID) &&	// ... which are valid for answer ...
   1639 					rr->resrec.rdatahash == rr2->resrec.namehash &&			// ... whose name is the name of the SRV target
   1640 					SameDomainName(&rr->resrec.rdata->u.srv.target, rr2->resrec.name))
   1641 					AddRecordToResponseList(nrpp, rr2, rr);
   1642 			}
   1643 		else if (RRTypeIsAddressType(rr->resrec.rrtype))	// For A or AAAA, put counterpart as additional
   1644 			{
   1645 			for (rr2=m->ResourceRecords; rr2; rr2=rr2->next)					// Scan list of resource records
   1646 				if (RRTypeIsAddressType(rr2->resrec.rrtype) &&					// For all address records (A/AAAA) ...
   1647 					ResourceRecordIsValidInterfaceAnswer(rr2, InterfaceID) &&	// ... which are valid for answer ...
   1648 					rr->resrec.namehash == rr2->resrec.namehash &&				// ... and have the same name
   1649 					SameDomainName(rr->resrec.name, rr2->resrec.name))
   1650 					AddRecordToResponseList(nrpp, rr2, rr);
   1651 			}
   1652 		else if (rr->resrec.rrtype == kDNSType_PTR)			// For service PTR, see if we want to add DeviceInfo record
   1653 			{
   1654 			if (ResourceRecordIsValidInterfaceAnswer(&m->DeviceInfo, InterfaceID) &&
   1655 				SameDomainLabel(rr->resrec.rdata->u.name.c, m->DeviceInfo.resrec.name->c))
   1656 				AddRecordToResponseList(nrpp, &m->DeviceInfo, rr);
   1657 			}
   1658 		}
   1659 	}
   1660 
   1661 mDNSlocal void SendDelayedUnicastResponse(mDNS *const m, const mDNSAddr *const dest, const mDNSInterfaceID InterfaceID)
   1662 	{
   1663 	AuthRecord *rr;
   1664 	AuthRecord  *ResponseRecords = mDNSNULL;
   1665 	AuthRecord **nrp             = &ResponseRecords;
   1666 	NetworkInterfaceInfo *intf = FirstInterfaceForID(m, InterfaceID);
   1667 
   1668 	// Make a list of all our records that need to be unicast to this destination
   1669 	for (rr = m->ResourceRecords; rr; rr=rr->next)
   1670 		{
   1671 		// If we find we can no longer unicast this answer, clear ImmedUnicast
   1672 		if (rr->ImmedAnswer == mDNSInterfaceMark               ||
   1673 			mDNSSameIPv4Address(rr->v4Requester, onesIPv4Addr) ||
   1674 			mDNSSameIPv6Address(rr->v6Requester, onesIPv6Addr)  )
   1675 			rr->ImmedUnicast = mDNSfalse;
   1676 
   1677 		if (rr->ImmedUnicast && rr->ImmedAnswer == InterfaceID)
   1678 			{
   1679 			if ((dest->type == mDNSAddrType_IPv4 && mDNSSameIPv4Address(rr->v4Requester, dest->ip.v4)) ||
   1680 				(dest->type == mDNSAddrType_IPv6 && mDNSSameIPv6Address(rr->v6Requester, dest->ip.v6)))
   1681 				{
   1682 				rr->ImmedAnswer  = mDNSNULL;				// Clear the state fields
   1683 				rr->ImmedUnicast = mDNSfalse;
   1684 				rr->v4Requester  = zerov4Addr;
   1685 				rr->v6Requester  = zerov6Addr;
   1686 
   1687 				// Only sent records registered for P2P over P2P interfaces
   1688 				if (intf && !mDNSPlatformValidRecordForInterface(rr, intf))
   1689 					{
   1690 					LogInfo("SendDelayedUnicastResponse: Not sending %s, on %s", ARDisplayString(m, rr), InterfaceNameForID(m, InterfaceID));
   1691 					continue;
   1692 					}
   1693 
   1694 				if (rr->NextResponse == mDNSNULL && nrp != &rr->NextResponse)	// rr->NR_AnswerTo
   1695 					{ rr->NR_AnswerTo = (mDNSu8*)~0; *nrp = rr; nrp = &rr->NextResponse; }
   1696 				}
   1697 			}
   1698 		}
   1699 
   1700 	AddAdditionalsToResponseList(m, ResponseRecords, &nrp, InterfaceID);
   1701 
   1702 	while (ResponseRecords)
   1703 		{
   1704 		mDNSu8 *responseptr = m->omsg.data;
   1705 		mDNSu8 *newptr;
   1706 		InitializeDNSMessage(&m->omsg.h, zeroID, ResponseFlags);
   1707 
   1708 		// Put answers in the packet
   1709 		while (ResponseRecords && ResponseRecords->NR_AnswerTo)
   1710 			{
   1711 			rr = ResponseRecords;
   1712 			if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
   1713 				rr->resrec.rrclass |= kDNSClass_UniqueRRSet;		// Temporarily set the cache flush bit so PutResourceRecord will set it
   1714 			newptr = PutResourceRecord(&m->omsg, responseptr, &m->omsg.h.numAnswers, &rr->resrec);
   1715 			rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet;			// Make sure to clear cache flush bit back to normal state
   1716 			if (!newptr && m->omsg.h.numAnswers) break;	// If packet full, send it now
   1717 			if (newptr) responseptr = newptr;
   1718 			ResponseRecords = rr->NextResponse;
   1719 			rr->NextResponse    = mDNSNULL;
   1720 			rr->NR_AnswerTo     = mDNSNULL;
   1721 			rr->NR_AdditionalTo = mDNSNULL;
   1722 			rr->RequireGoodbye  = mDNStrue;
   1723 			}
   1724 
   1725 		// Add additionals, if there's space
   1726 		while (ResponseRecords && !ResponseRecords->NR_AnswerTo)
   1727 			{
   1728 			rr = ResponseRecords;
   1729 			if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
   1730 				rr->resrec.rrclass |= kDNSClass_UniqueRRSet;		// Temporarily set the cache flush bit so PutResourceRecord will set it
   1731 			newptr = PutResourceRecord(&m->omsg, responseptr, &m->omsg.h.numAdditionals, &rr->resrec);
   1732 			rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet;			// Make sure to clear cache flush bit back to normal state
   1733 
   1734 			if (newptr) responseptr = newptr;
   1735 			if (newptr && m->omsg.h.numAnswers) rr->RequireGoodbye = mDNStrue;
   1736 			else if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask) rr->ImmedAnswer = mDNSInterfaceMark;
   1737 			ResponseRecords = rr->NextResponse;
   1738 			rr->NextResponse    = mDNSNULL;
   1739 			rr->NR_AnswerTo     = mDNSNULL;
   1740 			rr->NR_AdditionalTo = mDNSNULL;
   1741 			}
   1742 
   1743 		if (m->omsg.h.numAnswers)
   1744 			mDNSSendDNSMessage(m, &m->omsg, responseptr, InterfaceID, mDNSNULL, dest, MulticastDNSPort, mDNSNULL, mDNSNULL);
   1745 		}
   1746 	}
   1747 
   1748 // CompleteDeregistration guarantees that on exit the record will have been cut from the m->ResourceRecords list
   1749 // and the client's mStatus_MemFree callback will have been invoked
   1750 mDNSexport void CompleteDeregistration(mDNS *const m, AuthRecord *rr)
   1751 	{
   1752 	LogInfo("CompleteDeregistration: called for Resource record %s", ARDisplayString(m, rr));
   1753 	// Clearing rr->RequireGoodbye signals mDNS_Deregister_internal() that
   1754 	// it should go ahead and immediately dispose of this registration
   1755 	rr->resrec.RecordType = kDNSRecordTypeShared;
   1756 	rr->RequireGoodbye    = mDNSfalse;
   1757 	rr->WakeUp.HMAC       = zeroEthAddr;
   1758 	if (rr->AnsweredLocalQ) { AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse); rr->AnsweredLocalQ = mDNSfalse; }
   1759 	mDNS_Deregister_internal(m, rr, mDNS_Dereg_normal);		// Don't touch rr after this
   1760 	}
   1761 
   1762 // DiscardDeregistrations is used on shutdown and sleep to discard (forcibly and immediately)
   1763 // any deregistering records that remain in the m->ResourceRecords list.
   1764 // DiscardDeregistrations calls mDNS_Deregister_internal which can call a user callback,
   1765 // which may change the record list and/or question list.
   1766 // Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
   1767 mDNSlocal void DiscardDeregistrations(mDNS *const m)
   1768 	{
   1769 	if (m->CurrentRecord)
   1770 		LogMsg("DiscardDeregistrations ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
   1771 	m->CurrentRecord = m->ResourceRecords;
   1772 
   1773 	while (m->CurrentRecord)
   1774 		{
   1775 		AuthRecord *rr = m->CurrentRecord;
   1776 		if (!AuthRecord_uDNS(rr) && rr->resrec.RecordType == kDNSRecordTypeDeregistering)
   1777 			CompleteDeregistration(m, rr);		// Don't touch rr after this
   1778 		else
   1779 			m->CurrentRecord = rr->next;
   1780 		}
   1781 	}
   1782 
   1783 mDNSlocal mStatus GetLabelDecimalValue(const mDNSu8 *const src, mDNSu8 *dst)
   1784 	{
   1785 	int i, val = 0;
   1786 	if (src[0] < 1 || src[0] > 3) return(mStatus_Invalid);
   1787 	for (i=1; i<=src[0]; i++)
   1788 		{
   1789 		if (src[i] < '0' || src[i] > '9') return(mStatus_Invalid);
   1790 		val = val * 10 + src[i] - '0';
   1791 		}
   1792 	if (val > 255) return(mStatus_Invalid);
   1793 	*dst = (mDNSu8)val;
   1794 	return(mStatus_NoError);
   1795 	}
   1796 
   1797 mDNSlocal mStatus GetIPv4FromName(mDNSAddr *const a, const domainname *const name)
   1798 	{
   1799 	int skip = CountLabels(name) - 6;
   1800 	if (skip < 0) { LogMsg("GetIPFromName: Need six labels in IPv4 reverse mapping name %##s", name); return mStatus_Invalid; }
   1801 	if (GetLabelDecimalValue(SkipLeadingLabels(name, skip+3)->c, &a->ip.v4.b[0]) ||
   1802 		GetLabelDecimalValue(SkipLeadingLabels(name, skip+2)->c, &a->ip.v4.b[1]) ||
   1803 		GetLabelDecimalValue(SkipLeadingLabels(name, skip+1)->c, &a->ip.v4.b[2]) ||
   1804 		GetLabelDecimalValue(SkipLeadingLabels(name, skip+0)->c, &a->ip.v4.b[3])) return mStatus_Invalid;
   1805 	a->type = mDNSAddrType_IPv4;
   1806 	return(mStatus_NoError);
   1807 	}
   1808 
   1809 #define HexVal(X) ( ((X) >= '0' && (X) <= '9') ? ((X) - '0'     ) :   \
   1810 					((X) >= 'A' && (X) <= 'F') ? ((X) - 'A' + 10) :   \
   1811 					((X) >= 'a' && (X) <= 'f') ? ((X) - 'a' + 10) : -1)
   1812 
   1813 mDNSlocal mStatus GetIPv6FromName(mDNSAddr *const a, const domainname *const name)
   1814 	{
   1815 	int i, h, l;
   1816 	const domainname *n;
   1817 
   1818 	int skip = CountLabels(name) - 34;
   1819 	if (skip < 0) { LogMsg("GetIPFromName: Need 34 labels in IPv6 reverse mapping name %##s", name); return mStatus_Invalid; }
   1820 
   1821 	n = SkipLeadingLabels(name, skip);
   1822 	for (i=0; i<16; i++)
   1823 		{
   1824 		if (n->c[0] != 1) return mStatus_Invalid;
   1825 		l = HexVal(n->c[1]);
   1826 		n = (const domainname *)(n->c + 2);
   1827 
   1828 		if (n->c[0] != 1) return mStatus_Invalid;
   1829 		h = HexVal(n->c[1]);
   1830 		n = (const domainname *)(n->c + 2);
   1831 
   1832 		if (l<0 || h<0) return mStatus_Invalid;
   1833 		a->ip.v6.b[15-i] = (mDNSu8)((h << 4) | l);
   1834 		}
   1835 
   1836 	a->type = mDNSAddrType_IPv6;
   1837 	return(mStatus_NoError);
   1838 	}
   1839 
   1840 mDNSlocal mDNSs32 ReverseMapDomainType(const domainname *const name)
   1841 	{
   1842 	int skip = CountLabels(name) - 2;
   1843 	if (skip >= 0)
   1844 		{
   1845 		const domainname *suffix = SkipLeadingLabels(name, skip);
   1846 		if (SameDomainName(suffix, (const domainname*)"\x7" "in-addr" "\x4" "arpa")) return mDNSAddrType_IPv4;
   1847 		if (SameDomainName(suffix, (const domainname*)"\x3" "ip6"     "\x4" "arpa")) return mDNSAddrType_IPv6;
   1848 		}
   1849 	return(mDNSAddrType_None);
   1850 	}
   1851 
   1852 mDNSlocal void SendARP(mDNS *const m, const mDNSu8 op, const AuthRecord *const rr,
   1853 	const mDNSv4Addr *const spa, const mDNSEthAddr *const tha, const mDNSv4Addr *const tpa, const mDNSEthAddr *const dst)
   1854 	{
   1855 	int i;
   1856 	mDNSu8 *ptr = m->omsg.data;
   1857 	NetworkInterfaceInfo *intf = FirstInterfaceForID(m, rr->resrec.InterfaceID);
   1858 	if (!intf) { LogMsg("SendARP: No interface with InterfaceID %p found %s", rr->resrec.InterfaceID, ARDisplayString(m,rr)); return; }
   1859 
   1860 	// 0x00 Destination address
   1861 	for (i=0; i<6; i++) *ptr++ = dst->b[i];
   1862 
   1863 	// 0x06 Source address (Note: Since we don't currently set the BIOCSHDRCMPLT option, BPF will fill in the real interface address for us)
   1864 	for (i=0; i<6; i++) *ptr++ = intf->MAC.b[0];
   1865 
   1866 	// 0x0C ARP Ethertype (0x0806)
   1867 	*ptr++ = 0x08; *ptr++ = 0x06;
   1868 
   1869 	// 0x0E ARP header
   1870 	*ptr++ = 0x00; *ptr++ = 0x01;	// Hardware address space; Ethernet = 1
   1871 	*ptr++ = 0x08; *ptr++ = 0x00;	// Protocol address space; IP = 0x0800
   1872 	*ptr++ = 6;						// Hardware address length
   1873 	*ptr++ = 4;						// Protocol address length
   1874 	*ptr++ = 0x00; *ptr++ = op;		// opcode; Request = 1, Response = 2
   1875 
   1876 	// 0x16 Sender hardware address (our MAC address)
   1877 	for (i=0; i<6; i++) *ptr++ = intf->MAC.b[i];
   1878 
   1879 	// 0x1C Sender protocol address
   1880 	for (i=0; i<4; i++) *ptr++ = spa->b[i];
   1881 
   1882 	// 0x20 Target hardware address
   1883 	for (i=0; i<6; i++) *ptr++ = tha->b[i];
   1884 
   1885 	// 0x26 Target protocol address
   1886 	for (i=0; i<4; i++) *ptr++ = tpa->b[i];
   1887 
   1888 	// 0x2A Total ARP Packet length 42 bytes
   1889 	mDNSPlatformSendRawPacket(m->omsg.data, ptr, rr->resrec.InterfaceID);
   1890 	}
   1891 
   1892 mDNSlocal mDNSu16 CheckSum(const void *const data, mDNSs32 length, mDNSu32 sum)
   1893 	{
   1894 	const mDNSu16 *ptr = data;
   1895 	while (length > 0) { length -= 2; sum += *ptr++; }
   1896 	sum = (sum & 0xFFFF) + (sum >> 16);
   1897 	sum = (sum & 0xFFFF) + (sum >> 16);
   1898 	return(sum != 0xFFFF ? sum : 0);
   1899 	}
   1900 
   1901 mDNSlocal mDNSu16 IPv6CheckSum(const mDNSv6Addr *const src, const mDNSv6Addr *const dst, const mDNSu8 protocol, const void *const data, const mDNSu32 length)
   1902 	{
   1903 	IPv6PseudoHeader ph;
   1904 	ph.src = *src;
   1905 	ph.dst = *dst;
   1906 	ph.len.b[0] = length >> 24;
   1907 	ph.len.b[1] = length >> 16;
   1908 	ph.len.b[2] = length >> 8;
   1909 	ph.len.b[3] = length;
   1910 	ph.pro.b[0] = 0;
   1911 	ph.pro.b[1] = 0;
   1912 	ph.pro.b[2] = 0;
   1913 	ph.pro.b[3] = protocol;
   1914 	return CheckSum(&ph, sizeof(ph), CheckSum(data, length, 0));
   1915 	}
   1916 
   1917 mDNSlocal void SendNDP(mDNS *const m, const mDNSu8 op, const mDNSu8 flags, const AuthRecord *const rr,
   1918 	const mDNSv6Addr *const spa, const mDNSEthAddr *const tha, const mDNSv6Addr *const tpa, const mDNSEthAddr *const dst)
   1919 	{
   1920 	int i;
   1921 	mDNSOpaque16 checksum;
   1922 	mDNSu8 *ptr = m->omsg.data;
   1923 	// Some recipient hosts seem to ignore Neighbor Solicitations if the IPv6-layer destination address is not the
   1924 	// appropriate IPv6 solicited node multicast address, so we use that IPv6-layer destination address, even though
   1925 	// at the Ethernet-layer we unicast the packet to the intended target, to avoid wasting network bandwidth.
   1926 	const mDNSv6Addr mc = { { 0xFF,0x02,0x00,0x00, 0,0,0,0, 0,0,0,1, 0xFF,tpa->b[0xD],tpa->b[0xE],tpa->b[0xF] } };
   1927 	const mDNSv6Addr *const v6dst = (op == NDP_Sol) ? &mc : tpa;
   1928 	NetworkInterfaceInfo *intf = FirstInterfaceForID(m, rr->resrec.InterfaceID);
   1929 	if (!intf) { LogMsg("SendNDP: No interface with InterfaceID %p found %s", rr->resrec.InterfaceID, ARDisplayString(m,rr)); return; }
   1930 
   1931 	// 0x00 Destination address
   1932 	for (i=0; i<6; i++) *ptr++ = dst->b[i];
   1933 	// Right now we only send Neighbor Solicitations to verify whether the host we're proxying for has gone to sleep yet.
   1934 	// Since we know who we're looking for, we send it via Ethernet-layer unicast, rather than bothering every host on the
   1935 	// link with a pointless link-layer multicast.
   1936 	// Should we want to send traditional Neighbor Solicitations in the future, where we really don't know in advance what
   1937 	// Ethernet-layer address we're looking for, we'll need to send to the appropriate Ethernet-layer multicast address:
   1938 	// *ptr++ = 0x33;
   1939 	// *ptr++ = 0x33;
   1940 	// *ptr++ = 0xFF;
   1941 	// *ptr++ = tpa->b[0xD];
   1942 	// *ptr++ = tpa->b[0xE];
   1943 	// *ptr++ = tpa->b[0xF];
   1944 
   1945 	// 0x06 Source address (Note: Since we don't currently set the BIOCSHDRCMPLT option, BPF will fill in the real interface address for us)
   1946 	for (i=0; i<6; i++) *ptr++ = (tha ? *tha : intf->MAC).b[i];
   1947 
   1948 	// 0x0C IPv6 Ethertype (0x86DD)
   1949 	*ptr++ = 0x86; *ptr++ = 0xDD;
   1950 
   1951 	// 0x0E IPv6 header
   1952 	*ptr++ = 0x60; *ptr++ = 0x00; *ptr++ = 0x00; *ptr++ = 0x00;		// Version, Traffic Class, Flow Label
   1953 	*ptr++ = 0x00; *ptr++ = 0x20;									// Length
   1954 	*ptr++ = 0x3A;													// Protocol == ICMPv6
   1955 	*ptr++ = 0xFF;													// Hop Limit
   1956 
   1957 	// 0x16 Sender IPv6 address
   1958 	for (i=0; i<16; i++) *ptr++ = spa->b[i];
   1959 
   1960 	// 0x26 Destination IPv6 address
   1961 	for (i=0; i<16; i++) *ptr++ = v6dst->b[i];
   1962 
   1963 	// 0x36 NDP header
   1964 	*ptr++ = op;					// 0x87 == Neighbor Solicitation, 0x88 == Neighbor Advertisement
   1965 	*ptr++ = 0x00;					// Code
   1966 	*ptr++ = 0x00; *ptr++ = 0x00;	// Checksum placeholder (0x38, 0x39)
   1967 	*ptr++ = flags;
   1968 	*ptr++ = 0x00; *ptr++ = 0x00; *ptr++ = 0x00;
   1969 
   1970 	if (op == NDP_Sol)	// Neighbor Solicitation. The NDP "target" is the address we seek.
   1971 		{
   1972 		// 0x3E NDP target.
   1973 		for (i=0; i<16; i++) *ptr++ = tpa->b[i];
   1974 		// 0x4E Source Link-layer Address
   1975 		// <http://www.ietf.org/rfc/rfc2461.txt>
   1976 		// MUST NOT be included when the source IP address is the unspecified address.
   1977 		// Otherwise, on link layers that have addresses this option MUST be included
   1978 		// in multicast solicitations and SHOULD be included in unicast solicitations.
   1979 		if (!mDNSIPv6AddressIsZero(*spa))
   1980 			{
   1981 			*ptr++ = NDP_SrcLL;	// Option Type 1 == Source Link-layer Address
   1982 			*ptr++ = 0x01;		// Option length 1 (in units of 8 octets)
   1983 			for (i=0; i<6; i++) *ptr++ = (tha ? *tha : intf->MAC).b[i];
   1984 			}
   1985 		}
   1986 	else			// Neighbor Advertisement. The NDP "target" is the address we're giving information about.
   1987 		{
   1988 		// 0x3E NDP target.
   1989 		for (i=0; i<16; i++) *ptr++ = spa->b[i];
   1990 		// 0x4E Target Link-layer Address
   1991 		*ptr++ = NDP_TgtLL;	// Option Type 2 == Target Link-layer Address
   1992 		*ptr++ = 0x01;		// Option length 1 (in units of 8 octets)
   1993 		for (i=0; i<6; i++) *ptr++ = (tha ? *tha : intf->MAC).b[i];
   1994 		}
   1995 
   1996 	// 0x4E or 0x56 Total NDP Packet length 78 or 86 bytes
   1997 	m->omsg.data[0x13] = ptr - &m->omsg.data[0x36];		// Compute actual length
   1998 	checksum.NotAnInteger = ~IPv6CheckSum(spa, v6dst, 0x3A, &m->omsg.data[0x36], m->omsg.data[0x13]);
   1999 	m->omsg.data[0x38] = checksum.b[0];
   2000 	m->omsg.data[0x39] = checksum.b[1];
   2001 
   2002 	mDNSPlatformSendRawPacket(m->omsg.data, ptr, rr->resrec.InterfaceID);
   2003 	}
   2004 
   2005 mDNSlocal void SetupOwnerOpt(const mDNS *const m, const NetworkInterfaceInfo *const intf, rdataOPT *const owner)
   2006 	{
   2007 	owner->u.owner.vers     = 0;
   2008 	owner->u.owner.seq      = m->SleepSeqNum;
   2009 	owner->u.owner.HMAC     = m->PrimaryMAC;
   2010 	owner->u.owner.IMAC     = intf->MAC;
   2011 	owner->u.owner.password = zeroEthAddr;
   2012 
   2013 	// Don't try to compute the optlen until *after* we've set up the data fields
   2014 	// Right now the DNSOpt_Owner_Space macro does not depend on the owner->u.owner being set up correctly, but in the future it might
   2015 	owner->opt              = kDNSOpt_Owner;
   2016 	owner->optlen           = DNSOpt_Owner_Space(&m->PrimaryMAC, &intf->MAC) - 4;
   2017 	}
   2018 
   2019 mDNSlocal void GrantUpdateCredit(AuthRecord *rr)
   2020 	{
   2021 	if (++rr->UpdateCredits >= kMaxUpdateCredits) rr->NextUpdateCredit = 0;
   2022 	else rr->NextUpdateCredit = NonZeroTime(rr->NextUpdateCredit + kUpdateCreditRefreshInterval);
   2023 	}
   2024 
   2025 // Note about acceleration of announcements to facilitate automatic coalescing of
   2026 // multiple independent threads of announcements into a single synchronized thread:
   2027 // The announcements in the packet may be at different stages of maturity;
   2028 // One-second interval, two-second interval, four-second interval, and so on.
   2029 // After we've put in all the announcements that are due, we then consider
   2030 // whether there are other nearly-due announcements that are worth accelerating.
   2031 // To be eligible for acceleration, a record MUST NOT be older (further along
   2032 // its timeline) than the most mature record we've already put in the packet.
   2033 // In other words, younger records can have their timelines accelerated to catch up
   2034 // with their elder bretheren; this narrows the age gap and helps them eventually get in sync.
   2035 // Older records cannot have their timelines accelerated; this would just widen
   2036 // the gap between them and their younger bretheren and get them even more out of sync.
   2037 
   2038 // Note: SendResponses calls mDNS_Deregister_internal which can call a user callback, which may change
   2039 // the record list and/or question list.
   2040 // Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
   2041 mDNSlocal void SendResponses(mDNS *const m)
   2042 	{
   2043 	int pktcount = 0;
   2044 	AuthRecord *rr, *r2;
   2045 	mDNSs32 maxExistingAnnounceInterval = 0;
   2046 	const NetworkInterfaceInfo *intf = GetFirstActiveInterface(m->HostInterfaces);
   2047 
   2048 	m->NextScheduledResponse = m->timenow + 0x78000000;
   2049 
   2050 	if (m->SleepState == SleepState_Transferring) RetrySPSRegistrations(m);
   2051 
   2052 	for (rr = m->ResourceRecords; rr; rr=rr->next)
   2053 		if (rr->ImmedUnicast)
   2054 			{
   2055 			mDNSAddr v4 = { mDNSAddrType_IPv4, {{{0}}} };
   2056 			mDNSAddr v6 = { mDNSAddrType_IPv6, {{{0}}} };
   2057 			v4.ip.v4 = rr->v4Requester;
   2058 			v6.ip.v6 = rr->v6Requester;
   2059 			if (!mDNSIPv4AddressIsZero(rr->v4Requester)) SendDelayedUnicastResponse(m, &v4, rr->ImmedAnswer);
   2060 			if (!mDNSIPv6AddressIsZero(rr->v6Requester)) SendDelayedUnicastResponse(m, &v6, rr->ImmedAnswer);
   2061 			if (rr->ImmedUnicast)
   2062 				{
   2063 				LogMsg("SendResponses: ERROR: rr->ImmedUnicast still set: %s", ARDisplayString(m, rr));
   2064 				rr->ImmedUnicast = mDNSfalse;
   2065 				}
   2066 			}
   2067 
   2068 	// ***
   2069 	// *** 1. Setup: Set the SendRNow and ImmedAnswer fields to indicate which interface(s) the records need to be sent on
   2070 	// ***
   2071 
   2072 	// Run through our list of records, and decide which ones we're going to announce on all interfaces
   2073 	for (rr = m->ResourceRecords; rr; rr=rr->next)
   2074 		{
   2075 		while (rr->NextUpdateCredit && m->timenow - rr->NextUpdateCredit >= 0) GrantUpdateCredit(rr);
   2076 		if (TimeToAnnounceThisRecord(rr, m->timenow))
   2077 			{
   2078 			if (rr->resrec.RecordType == kDNSRecordTypeDeregistering)
   2079 				{
   2080 				if (!rr->WakeUp.HMAC.l[0])
   2081 					{
   2082 					if (rr->AnnounceCount) rr->ImmedAnswer = mDNSInterfaceMark;		// Send goodbye packet on all interfaces
   2083 					}
   2084 				else
   2085 					{
   2086 					LogSPS("SendResponses: Sending wakeup %2d for %.6a %s", rr->AnnounceCount-3, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
   2087 					SendWakeup(m, rr->resrec.InterfaceID, &rr->WakeUp.IMAC, &rr->WakeUp.password);
   2088 					for (r2 = rr; r2; r2=r2->next)
   2089 						if (r2->AnnounceCount && r2->resrec.InterfaceID == rr->resrec.InterfaceID && mDNSSameEthAddress(&r2->WakeUp.IMAC, &rr->WakeUp.IMAC))
   2090 							{
   2091 							// For now we only want to send a single Unsolicited Neighbor Advertisement restoring the address to the original
   2092 							// owner, because these packets can cause some IPv6 stacks to falsely conclude that there's an address conflict.
   2093 							if (r2->AddressProxy.type == mDNSAddrType_IPv6 && r2->AnnounceCount == WakeupCount)
   2094 								{
   2095 								LogSPS("NDP Announcement %2d Releasing traffic for H-MAC %.6a I-MAC %.6a %s",
   2096 									r2->AnnounceCount-3, &r2->WakeUp.HMAC, &r2->WakeUp.IMAC, ARDisplayString(m,r2));
   2097 								SendNDP(m, NDP_Adv, NDP_Override, r2, &r2->AddressProxy.ip.v6, &r2->WakeUp.IMAC, &AllHosts_v6, &AllHosts_v6_Eth);
   2098 								}
   2099 							r2->LastAPTime = m->timenow;
   2100 							// After 15 wakeups without success (maybe host has left the network) send three goodbyes instead
   2101 							if (--r2->AnnounceCount <= GoodbyeCount) r2->WakeUp.HMAC = zeroEthAddr;
   2102 							}
   2103 					}
   2104 				}
   2105 			else if (ResourceRecordIsValidAnswer(rr))
   2106 				{
   2107 				if (rr->AddressProxy.type)
   2108 					{
   2109 					rr->AnnounceCount--;
   2110 					rr->ThisAPInterval *= 2;
   2111 					rr->LastAPTime = m->timenow;
   2112 					if (rr->AddressProxy.type == mDNSAddrType_IPv4)
   2113 						{
   2114 						LogSPS("ARP Announcement %2d Capturing traffic for H-MAC %.6a I-MAC %.6a %s",
   2115 							rr->AnnounceCount, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m,rr));
   2116 						SendARP(m, 1, rr, &rr->AddressProxy.ip.v4, &zeroEthAddr, &rr->AddressProxy.ip.v4, &onesEthAddr);
   2117 						}
   2118 					else if (rr->AddressProxy.type == mDNSAddrType_IPv6)
   2119 						{
   2120 						LogSPS("NDP Announcement %2d Capturing traffic for H-MAC %.6a I-MAC %.6a %s",
   2121 							rr->AnnounceCount, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m,rr));
   2122 						SendNDP(m, NDP_Adv, NDP_Override, rr, &rr->AddressProxy.ip.v6, mDNSNULL, &AllHosts_v6, &AllHosts_v6_Eth);
   2123 						}
   2124 					}
   2125 				else
   2126 					{
   2127 					rr->ImmedAnswer = mDNSInterfaceMark;		// Send on all interfaces
   2128 					if (maxExistingAnnounceInterval < rr->ThisAPInterval)
   2129 						maxExistingAnnounceInterval = rr->ThisAPInterval;
   2130 					if (rr->UpdateBlocked) rr->UpdateBlocked = 0;
   2131 					}
   2132 				}
   2133 			}
   2134 		}
   2135 
   2136 	// Any interface-specific records we're going to send are marked as being sent on all appropriate interfaces (which is just one)
   2137 	// Eligible records that are more than half-way to their announcement time are accelerated
   2138 	for (rr = m->ResourceRecords; rr; rr=rr->next)
   2139 		if ((rr->resrec.InterfaceID && rr->ImmedAnswer) ||
   2140 			(rr->ThisAPInterval <= maxExistingAnnounceInterval &&
   2141 			TimeToAnnounceThisRecord(rr, m->timenow + rr->ThisAPInterval/2) &&
   2142 			!rr->AddressProxy.type && 					// Don't include ARP Annoucements when considering which records to accelerate
   2143 			ResourceRecordIsValidAnswer(rr)))
   2144 			rr->ImmedAnswer = mDNSInterfaceMark;		// Send on all interfaces
   2145 
   2146 	// When sending SRV records (particularly when announcing a new service) automatically add related Address record(s) as additionals
   2147 	// Note: Currently all address records are interface-specific, so it's safe to set ImmedAdditional to their InterfaceID,
   2148 	// which will be non-null. If by some chance there is an address record that's not interface-specific (should never happen)
   2149 	// then all that means is that it won't get sent -- which would not be the end of the world.
   2150 	for (rr = m->ResourceRecords; rr; rr=rr->next)
   2151 		{
   2152 		if (rr->ImmedAnswer && rr->resrec.rrtype == kDNSType_SRV)
   2153 			for (r2=m->ResourceRecords; r2; r2=r2->next)				// Scan list of resource records
   2154 				if (RRTypeIsAddressType(r2->resrec.rrtype) &&			// For all address records (A/AAAA) ...
   2155 					ResourceRecordIsValidAnswer(r2) &&					// ... which are valid for answer ...
   2156 					rr->LastMCTime - r2->LastMCTime >= 0 &&				// ... which we have not sent recently ...
   2157 					rr->resrec.rdatahash == r2->resrec.namehash &&		// ... whose name is the name of the SRV target
   2158 					SameDomainName(&rr->resrec.rdata->u.srv.target, r2->resrec.name) &&
   2159 					(rr->ImmedAnswer == mDNSInterfaceMark || rr->ImmedAnswer == r2->resrec.InterfaceID))
   2160 					r2->ImmedAdditional = r2->resrec.InterfaceID;		// ... then mark this address record for sending too
   2161 		// We also make sure we send the DeviceInfo TXT record too, if necessary
   2162 		// We check for RecordType == kDNSRecordTypeShared because we don't want to tag the
   2163 		// DeviceInfo TXT record onto a goodbye packet (RecordType == kDNSRecordTypeDeregistering).
   2164 		if (rr->ImmedAnswer && rr->resrec.RecordType == kDNSRecordTypeShared && rr->resrec.rrtype == kDNSType_PTR)
   2165 			if (ResourceRecordIsValidAnswer(&m->DeviceInfo) && SameDomainLabel(rr->resrec.rdata->u.name.c, m->DeviceInfo.resrec.name->c))
   2166 				{
   2167 				if (!m->DeviceInfo.ImmedAnswer) m->DeviceInfo.ImmedAnswer = rr->ImmedAnswer;
   2168 				else                            m->DeviceInfo.ImmedAnswer = mDNSInterfaceMark;
   2169 				}
   2170 		}
   2171 
   2172 	// If there's a record which is supposed to be unique that we're going to send, then make sure that we give
   2173 	// the whole RRSet as an atomic unit. That means that if we have any other records with the same name/type/class
   2174 	// then we need to mark them for sending too. Otherwise, if we set the kDNSClass_UniqueRRSet bit on a
   2175 	// record, then other RRSet members that have not been sent recently will get flushed out of client caches.
   2176 	// -- If a record is marked to be sent on a certain interface, make sure the whole set is marked to be sent on that interface
   2177 	// -- If any record is marked to be sent on all interfaces, make sure the whole set is marked to be sent on all interfaces
   2178 	for (rr = m->ResourceRecords; rr; rr=rr->next)
   2179 		if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
   2180 			{
   2181 			if (rr->ImmedAnswer)			// If we're sending this as answer, see that its whole RRSet is similarly marked
   2182 				{
   2183 				for (r2 = m->ResourceRecords; r2; r2=r2->next)
   2184 					if (ResourceRecordIsValidAnswer(r2))
   2185 						if (r2->ImmedAnswer != mDNSInterfaceMark &&
   2186 							r2->ImmedAnswer != rr->ImmedAnswer && SameResourceRecordSignature(r2, rr))
   2187 							r2->ImmedAnswer = !r2->ImmedAnswer ? rr->ImmedAnswer : mDNSInterfaceMark;
   2188 				}
   2189 			else if (rr->ImmedAdditional)	// If we're sending this as additional, see that its whole RRSet is similarly marked
   2190 				{
   2191 				for (r2 = m->ResourceRecords; r2; r2=r2->next)
   2192 					if (ResourceRecordIsValidAnswer(r2))
   2193 						if (r2->ImmedAdditional != rr->ImmedAdditional && SameResourceRecordSignature(r2, rr))
   2194 							r2->ImmedAdditional = rr->ImmedAdditional;
   2195 				}
   2196 			}
   2197 
   2198 	// Now set SendRNow state appropriately
   2199 	for (rr = m->ResourceRecords; rr; rr=rr->next)
   2200 		{
   2201 		if (rr->ImmedAnswer == mDNSInterfaceMark)		// Sending this record on all appropriate interfaces
   2202 			{
   2203 			rr->SendRNow = !intf ? mDNSNULL : (rr->resrec.InterfaceID) ? rr->resrec.InterfaceID : intf->InterfaceID;
   2204 			rr->ImmedAdditional = mDNSNULL;				// No need to send as additional if sending as answer
   2205 			rr->LastMCTime      = m->timenow;
   2206 			rr->LastMCInterface = rr->ImmedAnswer;
   2207 			// If we're announcing this record, and it's at least half-way to its ordained time, then consider this announcement done
   2208 			if (TimeToAnnounceThisRecord(rr, m->timenow + rr->ThisAPInterval/2))
   2209 				{
   2210 				rr->AnnounceCount--;
   2211 				if (rr->resrec.RecordType != kDNSRecordTypeDeregistering)
   2212 					rr->ThisAPInterval *= 2;
   2213 				rr->LastAPTime = m->timenow;
   2214 				debugf("Announcing %##s (%s) %d", rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype), rr->AnnounceCount);
   2215 				}
   2216 			}
   2217 		else if (rr->ImmedAnswer)						// Else, just respond to a single query on single interface:
   2218 			{
   2219 			rr->SendRNow        = rr->ImmedAnswer;		// Just respond on that interface
   2220 			rr->ImmedAdditional = mDNSNULL;				// No need to send as additional too
   2221 			rr->LastMCTime      = m->timenow;
   2222 			rr->LastMCInterface = rr->ImmedAnswer;
   2223 			}
   2224 		SetNextAnnounceProbeTime(m, rr);
   2225 		//if (rr->SendRNow) LogMsg("%-15.4a %s", &rr->v4Requester, ARDisplayString(m, rr));
   2226 		}
   2227 
   2228 	// ***
   2229 	// *** 2. Loop through interface list, sending records as appropriate
   2230 	// ***
   2231 
   2232 	while (intf)
   2233 		{
   2234 		const int OwnerRecordSpace = (m->AnnounceOwner && intf->MAC.l[0]) ? DNSOpt_Header_Space + DNSOpt_Owner_Space(&m->PrimaryMAC, &intf->MAC) : 0;
   2235 		int numDereg    = 0;
   2236 		int numAnnounce = 0;
   2237 		int numAnswer   = 0;
   2238 		mDNSu8 *responseptr = m->omsg.data;
   2239 		mDNSu8 *newptr;