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
62WCFConnection *WCFConnectionNew(void) __attribute__((weak_import));
63void 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
75mDNSlocal void BeginSleepProcessing(mDNS *const m);
76mDNSlocal void RetrySPSRegistrations(mDNS *const m);
77mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAddr *EthAddr, mDNSOpaque48 *password);
78mDNSlocal mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
79mDNSlocal mDNSBool LocalRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
80mDNSlocal 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
96mDNSexport 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
126mDNSlocal 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
139mDNSexport 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
159mDNSlocal 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
170mDNSlocal 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
182mDNSlocal 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
238mDNSexport 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
247mDNSexport AuthGroup *AuthGroupForRecord(AuthHash *r, const mDNSu32 slot, const ResourceRecord *const rr)
248	{
249	return(AuthGroupForName(r, slot, rr->namehash, rr->name));
250	}
251
252mDNSlocal 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
280mDNSexport 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
295mDNSexport 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
322mDNSexport 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
331mDNSlocal 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
336mDNSexport 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
365mDNSlocal 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
372mDNSexport 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
379mDNSlocal 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
393mDNSlocal 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
442mDNSlocal 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
491mDNSlocal 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
524mDNSlocal 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
615mDNSlocal 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
636mDNSlocal 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.
658mDNSlocal 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
675mDNSlocal 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
700mDNSlocal 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
788mDNSlocal 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
817mDNSlocal 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
857mDNSlocal 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
870mDNSexport 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
951mDNSlocal 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
978mDNSlocal 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
1001mDNSlocal 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
1024mDNSexport 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
1328mDNSlocal 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
1347mDNSlocal 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
1360mDNSexport 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
1605mDNSlocal 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
1620mDNSlocal 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
1661mDNSlocal 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
1750mDNSexport 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.
1767mDNSlocal 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
1783mDNSlocal 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
1797mDNSlocal 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
1813mDNSlocal 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
1840mDNSlocal 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
1852mDNSlocal 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
1892mDNSlocal 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
1901mDNSlocal 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
1917mDNSlocal 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
2005mDNSlocal 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
2019mDNSlocal 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.
2041mDNSlocal 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;
2240		InitializeDNSMessage(&m->omsg.h, zeroID, ResponseFlags);
2241
2242		// First Pass. Look for:
2243		// 1. Deregistering records that need to send their goodbye packet
2244		// 2. Updated records that need to retract their old data
2245		// 3. Answers and announcements we need to send
2246		for (rr = m->ResourceRecords; rr; rr=rr->next)
2247			{
2248
2249			// Skip this interface if the record InterfaceID is *Any and the record is not
2250			// appropriate for the interface type.
2251			if ((rr->SendRNow == intf->InterfaceID) &&
2252				((rr->resrec.InterfaceID == mDNSInterface_Any) && !mDNSPlatformValidRecordForInterface(rr, intf)))
2253				{
2254					LogInfo("SendResponses: Not sending %s, on %s", ARDisplayString(m, rr), InterfaceNameForID(m, rr->SendRNow));
2255					rr->SendRNow = GetNextActiveInterfaceID(intf);
2256				}
2257			else if (rr->SendRNow == intf->InterfaceID)
2258				{
2259				RData  *OldRData    = rr->resrec.rdata;
2260				mDNSu16 oldrdlength = rr->resrec.rdlength;
2261				mDNSu8 active = (mDNSu8)
2262					(rr->resrec.RecordType != kDNSRecordTypeDeregistering &&
2263					(m->SleepState != SleepState_Sleeping || intf->SPSAddr[0].type || intf->SPSAddr[1].type || intf->SPSAddr[2].type));
2264				newptr = mDNSNULL;
2265				if (rr->NewRData && active)
2266					{
2267					// See if we should send a courtesy "goodbye" for the old data before we replace it.
2268					if (ResourceRecordIsValidAnswer(rr) && rr->resrec.RecordType == kDNSRecordTypeShared && rr->RequireGoodbye)
2269						{
2270						newptr = PutRR_OS_TTL(responseptr, &m->omsg.h.numAnswers, &rr->resrec, 0);
2271						if (newptr) { responseptr = newptr; numDereg++; rr->RequireGoodbye = mDNSfalse; }
2272						else continue; // If this packet is already too full to hold the goodbye for this record, skip it for now and we'll retry later
2273						}
2274					SetNewRData(&rr->resrec, rr->NewRData, rr->newrdlength);
2275					}
2276
2277				if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
2278					rr->resrec.rrclass |= kDNSClass_UniqueRRSet;		// Temporarily set the cache flush bit so PutResourceRecord will set it
2279				newptr = PutRR_OS_TTL(responseptr, &m->omsg.h.numAnswers, &rr->resrec, active ? rr->resrec.rroriginalttl : 0);
2280				rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet;			// Make sure to clear cache flush bit back to normal state
2281				if (newptr)
2282					{
2283					responseptr = newptr;
2284					rr->RequireGoodbye = active;
2285					if (rr->resrec.RecordType == kDNSRecordTypeDeregistering) numDereg++;
2286					else if (rr->LastAPTime == m->timenow) numAnnounce++; else numAnswer++;
2287					}
2288
2289				if (rr->NewRData && active)
2290					SetNewRData(&rr->resrec, OldRData, oldrdlength);
2291
2292				// The first time through (pktcount==0), if this record is verified unique
2293				// (i.e. typically A, AAAA, SRV, TXT and reverse-mapping PTR), set the flag to add an NSEC too.
2294				if (!pktcount && active && (rr->resrec.RecordType & kDNSRecordTypeActiveUniqueMask) && !rr->SendNSECNow)
2295					rr->SendNSECNow = mDNSInterfaceMark;
2296
2297				if (newptr)		// If succeeded in sending, advance to next interface
2298					{
2299					// If sending on all interfaces, go to next interface; else we're finished now
2300					if (rr->ImmedAnswer == mDNSInterfaceMark && rr->resrec.InterfaceID == mDNSInterface_Any)
2301						rr->SendRNow = GetNextActiveInterfaceID(intf);
2302					else
2303						rr->SendRNow = mDNSNULL;
2304					}
2305				}
2306			}
2307
2308		// Second Pass. Add additional records, if there's space.
2309		newptr = responseptr;
2310		for (rr = m->ResourceRecords; rr; rr=rr->next)
2311			if (rr->ImmedAdditional == intf->InterfaceID)
2312				if (ResourceRecordIsValidAnswer(rr))
2313					{
2314					// If we have at least one answer already in the packet, then plan to add additionals too
2315					mDNSBool SendAdditional = (m->omsg.h.numAnswers > 0);
2316
2317					// If we're not planning to send any additionals, but this record is a unique one, then
2318					// make sure we haven't already sent any other members of its RRSet -- if we have, then they
2319					// will have had the cache flush bit set, so now we need to finish the job and send the rest.
2320					if (!SendAdditional && (rr->resrec.RecordType & kDNSRecordTypeUniqueMask))
2321						{
2322						const AuthRecord *a;
2323						for (a = m->ResourceRecords; a; a=a->next)
2324							if (a->LastMCTime      == m->timenow &&
2325								a->LastMCInterface == intf->InterfaceID &&
2326								SameResourceRecordSignature(a, rr)) { SendAdditional = mDNStrue; break; }
2327						}
2328					if (!SendAdditional)					// If we don't want to send this after all,
2329						rr->ImmedAdditional = mDNSNULL;		// then cancel its ImmedAdditional field
2330					else if (newptr)						// Else, try to add it if we can
2331						{
2332						// The first time through (pktcount==0), if this record is verified unique
2333						// (i.e. typically A, AAAA, SRV, TXT and reverse-mapping PTR), set the flag to add an NSEC too.
2334						if (!pktcount && (rr->resrec.RecordType & kDNSRecordTypeActiveUniqueMask) && !rr->SendNSECNow)
2335							rr->SendNSECNow = mDNSInterfaceMark;
2336
2337						if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
2338							rr->resrec.rrclass |= kDNSClass_UniqueRRSet;	// Temporarily set the cache flush bit so PutResourceRecord will set it
2339						newptr = PutRR_OS(newptr, &m->omsg.h.numAdditionals, &rr->resrec);
2340						rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet;		// Make sure to clear cache flush bit back to normal state
2341						if (newptr)
2342							{
2343							responseptr = newptr;
2344							rr->ImmedAdditional = mDNSNULL;
2345							rr->RequireGoodbye = mDNStrue;
2346							// If we successfully put this additional record in the packet, we record LastMCTime & LastMCInterface.
2347							// This matters particularly in the case where we have more than one IPv6 (or IPv4) address, because otherwise,
2348							// when we see our own multicast with the cache flush bit set, if we haven't set LastMCTime, then we'll get
2349							// all concerned and re-announce our record again to make sure it doesn't get flushed from peer caches.
2350							rr->LastMCTime      = m->timenow;
2351							rr->LastMCInterface = intf->InterfaceID;
2352							}
2353						}
2354					}
2355
2356		// Third Pass. Add NSEC records, if there's space.
2357		// When we're generating an NSEC record in response to a specify query for that type
2358		// (recognized by rr->SendNSECNow == intf->InterfaceID) we should really put the NSEC in the Answer Section,
2359		// not Additional Section, but for now it's easier to handle both cases in this Additional Section loop here.
2360		for (rr = m->ResourceRecords; rr; rr=rr->next)
2361			if (rr->SendNSECNow == mDNSInterfaceMark || rr->SendNSECNow == intf->InterfaceID)
2362				{
2363				AuthRecord nsec;
2364				mDNS_SetupResourceRecord(&nsec, mDNSNULL, mDNSInterface_Any, kDNSType_NSEC, rr->resrec.rroriginalttl, kDNSRecordTypeUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
2365				nsec.resrec.rrclass |= kDNSClass_UniqueRRSet;
2366				AssignDomainName(&nsec.namestorage, rr->resrec.name);
2367				mDNSPlatformMemZero(nsec.rdatastorage.u.nsec.bitmap, sizeof(nsec.rdatastorage.u.nsec.bitmap));
2368				for (r2 = m->ResourceRecords; r2; r2=r2->next)
2369					if (ResourceRecordIsValidAnswer(r2) && SameResourceRecordNameClassInterface(r2, rr))
2370						{
2371						if (r2->resrec.rrtype >= kDNSQType_ANY) { LogMsg("Can't create NSEC for record %s", ARDisplayString(m, r2)); break; }
2372						else nsec.rdatastorage.u.nsec.bitmap[r2->resrec.rrtype >> 3] |= 128 >> (r2->resrec.rrtype & 7);
2373						}
2374				newptr = responseptr;
2375				if (!r2)	// If we successfully built our NSEC record, add it to the packet now
2376					{
2377					newptr = PutRR_OS(responseptr, &m->omsg.h.numAdditionals, &nsec.resrec);
2378					if (newptr) responseptr = newptr;
2379					}
2380
2381				// If we successfully put the NSEC record, clear the SendNSECNow flag
2382				// If we consider this NSEC optional, then we unconditionally clear the SendNSECNow flag, even if we fail to put this additional record
2383				if (newptr || rr->SendNSECNow == mDNSInterfaceMark)
2384					{
2385					rr->SendNSECNow = mDNSNULL;
2386					// Run through remainder of list clearing SendNSECNow flag for all other records which would generate the same NSEC
2387					for (r2 = rr->next; r2; r2=r2->next)
2388						if (SameResourceRecordNameClassInterface(r2, rr))
2389							if (r2->SendNSECNow == mDNSInterfaceMark || r2->SendNSECNow == intf->InterfaceID)
2390								r2->SendNSECNow = mDNSNULL;
2391					}
2392				}
2393
2394		if (m->omsg.h.numAnswers || m->omsg.h.numAdditionals)
2395			{
2396			// If we have data to send, add OWNER option if necessary, then send packet
2397
2398			if (OwnerRecordSpace)
2399				{
2400				AuthRecord opt;
2401				mDNS_SetupResourceRecord(&opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
2402				opt.resrec.rrclass    = NormalMaxDNSMessageData;
2403				opt.resrec.rdlength   = sizeof(rdataOPT);	// One option in this OPT record
2404				opt.resrec.rdestimate = sizeof(rdataOPT);
2405				SetupOwnerOpt(m, intf, &opt.resrec.rdata->u.opt[0]);
2406				newptr = PutResourceRecord(&m->omsg, responseptr, &m->omsg.h.numAdditionals, &opt.resrec);
2407				if (newptr) { responseptr = newptr; LogSPS("SendResponses put   %s", ARDisplayString(m, &opt)); }
2408				else if (m->omsg.h.numAnswers + m->omsg.h.numAuthorities + m->omsg.h.numAdditionals == 1)
2409					LogSPS("SendResponses: No space in packet for Owner OPT record (%d/%d/%d/%d) %s",
2410						m->omsg.h.numQuestions, m->omsg.h.numAnswers, m->omsg.h.numAuthorities, m->omsg.h.numAdditionals, ARDisplayString(m, &opt));
2411				else
2412					LogMsg("SendResponses: How did we fail to have space for Owner OPT record (%d/%d/%d/%d) %s",
2413						m->omsg.h.numQuestions, m->omsg.h.numAnswers, m->omsg.h.numAuthorities, m->omsg.h.numAdditionals, ARDisplayString(m, &opt));
2414				}
2415
2416			debugf("SendResponses: Sending %d Deregistration%s, %d Announcement%s, %d Answer%s, %d Additional%s on %p",
2417				numDereg,                 numDereg                 == 1 ? "" : "s",
2418				numAnnounce,              numAnnounce              == 1 ? "" : "s",
2419				numAnswer,                numAnswer                == 1 ? "" : "s",
2420				m->omsg.h.numAdditionals, m->omsg.h.numAdditionals == 1 ? "" : "s", intf->InterfaceID);
2421
2422			if (intf->IPv4Available) mDNSSendDNSMessage(m, &m->omsg, responseptr, intf->InterfaceID, mDNSNULL, &AllDNSLinkGroup_v4, MulticastDNSPort, mDNSNULL, mDNSNULL);
2423			if (intf->IPv6Available) mDNSSendDNSMessage(m, &m->omsg, responseptr, intf->InterfaceID, mDNSNULL, &AllDNSLinkGroup_v6, MulticastDNSPort, mDNSNULL, mDNSNULL);
2424			if (!m->SuppressSending) m->SuppressSending = NonZeroTime(m->timenow + (mDNSPlatformOneSecond+9)/10);
2425			if (++pktcount >= 1000) { LogMsg("SendResponses exceeded loop limit %d: giving up", pktcount); break; }
2426			// There might be more things to send on this interface, so go around one more time and try again.
2427			}
2428		else	// Nothing more to send on this interface; go to next
2429			{
2430			const NetworkInterfaceInfo *next = GetFirstActiveInterface(intf->next);
2431			#if MDNS_DEBUGMSGS && 0
2432			const char *const msg = next ? "SendResponses: Nothing more on %p; moving to %p" : "SendResponses: Nothing more on %p";
2433			debugf(msg, intf, next);
2434			#endif
2435			intf = next;
2436			pktcount = 0;		// When we move to a new interface, reset packet count back to zero -- NSEC generation logic uses it
2437			}
2438		}
2439
2440	// ***
2441	// *** 3. Cleanup: Now that everything is sent, call client callback functions, and reset state variables
2442	// ***
2443
2444	if (m->CurrentRecord)
2445		LogMsg("SendResponses ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
2446	m->CurrentRecord = m->ResourceRecords;
2447	while (m->CurrentRecord)
2448		{
2449		rr = m->CurrentRecord;
2450		m->CurrentRecord = rr->next;
2451
2452		if (rr->SendRNow)
2453			{
2454			if (rr->ARType != AuthRecordLocalOnly && rr->ARType != AuthRecordP2P)
2455				LogMsg("SendResponses: No active interface %p to send: %p %02X %s", rr->SendRNow, rr->resrec.InterfaceID, rr->resrec.RecordType, ARDisplayString(m, rr));
2456			rr->SendRNow = mDNSNULL;
2457			}
2458
2459		if (rr->ImmedAnswer || rr->resrec.RecordType == kDNSRecordTypeDeregistering)
2460			{
2461			if (rr->NewRData) CompleteRDataUpdate(m, rr);	// Update our rdata, clear the NewRData pointer, and return memory to the client
2462
2463			if (rr->resrec.RecordType == kDNSRecordTypeDeregistering && rr->AnnounceCount == 0)
2464				{
2465				// For Unicast, when we get the response from the server, we will call CompleteDeregistration
2466				if (!AuthRecord_uDNS(rr)) CompleteDeregistration(m, rr);		// Don't touch rr after this
2467				}
2468			else
2469				{
2470				rr->ImmedAnswer  = mDNSNULL;
2471				rr->ImmedUnicast = mDNSfalse;
2472				rr->v4Requester  = zerov4Addr;
2473				rr->v6Requester  = zerov6Addr;
2474				}
2475			}
2476		}
2477	verbosedebugf("SendResponses: Next in %ld ticks", m->NextScheduledResponse - m->timenow);
2478	}
2479
2480// Calling CheckCacheExpiration() is an expensive operation because it has to look at the entire cache,
2481// so we want to be lazy about how frequently we do it.
2482// 1. If a cache record is currently referenced by *no* active questions,
2483//    then we don't mind expiring it up to a minute late (who will know?)
2484// 2. Else, if a cache record is due for some of its final expiration queries,
2485//    we'll allow them to be late by up to 2% of the TTL
2486// 3. Else, if a cache record has completed all its final expiration queries without success,
2487//    and is expiring, and had an original TTL more than ten seconds, we'll allow it to be one second late
2488// 4. Else, it is expiring and had an original TTL of ten seconds or less (includes explicit goodbye packets),
2489//    so allow at most 1/10 second lateness
2490// 5. For records with rroriginalttl set to zero, that means we really want to delete them immediately
2491//    (we have a new record with DelayDelivery set, waiting for the old record to go away before we can notify clients).
2492#define CacheCheckGracePeriod(RR) (                                                   \
2493	((RR)->CRActiveQuestion == mDNSNULL            ) ? (60 * mDNSPlatformOneSecond) : \
2494	((RR)->UnansweredQueries < MaxUnansweredQueries) ? (TicksTTL(rr)/50)            : \
2495	((RR)->resrec.rroriginalttl > 10               ) ? (mDNSPlatformOneSecond)      : \
2496	((RR)->resrec.rroriginalttl > 0                ) ? (mDNSPlatformOneSecond/10)   : 0)
2497
2498#define NextCacheCheckEvent(RR) ((RR)->NextRequiredQuery + CacheCheckGracePeriod(RR))
2499
2500mDNSexport void ScheduleNextCacheCheckTime(mDNS *const m, const mDNSu32 slot, const mDNSs32 event)
2501	{
2502	if (m->rrcache_nextcheck[slot] - event > 0)
2503		m->rrcache_nextcheck[slot] = event;
2504	if (m->NextCacheCheck          - event > 0)
2505		m->NextCacheCheck          = event;
2506	}
2507
2508// Note: MUST call SetNextCacheCheckTimeForRecord any time we change:
2509// rr->TimeRcvd
2510// rr->resrec.rroriginalttl
2511// rr->UnansweredQueries
2512// rr->CRActiveQuestion
2513mDNSlocal void SetNextCacheCheckTimeForRecord(mDNS *const m, CacheRecord *const rr)
2514	{
2515	rr->NextRequiredQuery = RRExpireTime(rr);
2516
2517	// If we have an active question, then see if we want to schedule a refresher query for this record.
2518	// Usually we expect to do four queries, at 80-82%, 85-87%, 90-92% and then 95-97% of the TTL.
2519	if (rr->CRActiveQuestion && rr->UnansweredQueries < MaxUnansweredQueries)
2520		{
2521		rr->NextRequiredQuery -= TicksTTL(rr)/20 * (MaxUnansweredQueries - rr->UnansweredQueries);
2522		rr->NextRequiredQuery += mDNSRandom((mDNSu32)TicksTTL(rr)/50);
2523		verbosedebugf("SetNextCacheCheckTimeForRecord: NextRequiredQuery in %ld sec CacheCheckGracePeriod %d ticks for %s",
2524			(rr->NextRequiredQuery - m->timenow) / mDNSPlatformOneSecond, CacheCheckGracePeriod(rr), CRDisplayString(m,rr));
2525		}
2526
2527	ScheduleNextCacheCheckTime(m, HashSlot(rr->resrec.name), NextCacheCheckEvent(rr));
2528	}
2529
2530#define kMinimumReconfirmTime                     ((mDNSu32)mDNSPlatformOneSecond *  5)
2531#define kDefaultReconfirmTimeForWake              ((mDNSu32)mDNSPlatformOneSecond *  5)
2532#define kDefaultReconfirmTimeForNoAnswer          ((mDNSu32)mDNSPlatformOneSecond *  5)
2533#define kDefaultReconfirmTimeForFlappingInterface ((mDNSu32)mDNSPlatformOneSecond * 30)
2534
2535mDNSlocal mStatus mDNS_Reconfirm_internal(mDNS *const m, CacheRecord *const rr, mDNSu32 interval)
2536	{
2537	if (interval < kMinimumReconfirmTime)
2538		interval = kMinimumReconfirmTime;
2539	if (interval > 0x10000000)	// Make sure interval doesn't overflow when we multiply by four below
2540		interval = 0x10000000;
2541
2542	// If the expected expiration time for this record is more than interval+33%, then accelerate its expiration
2543	if (RRExpireTime(rr) - m->timenow > (mDNSs32)((interval * 4) / 3))
2544		{
2545		// Add a 33% random amount to the interval, to avoid synchronization between multiple hosts
2546		// For all the reconfirmations in a given batch, we want to use the same random value
2547		// so that the reconfirmation questions can be grouped into a single query packet
2548		if (!m->RandomReconfirmDelay) m->RandomReconfirmDelay = 1 + mDNSRandom(0x3FFFFFFF);
2549		interval += m->RandomReconfirmDelay % ((interval/3) + 1);
2550		rr->TimeRcvd          = m->timenow - (mDNSs32)interval * 3;
2551		rr->resrec.rroriginalttl     = (interval * 4 + mDNSPlatformOneSecond - 1) / mDNSPlatformOneSecond;
2552		SetNextCacheCheckTimeForRecord(m, rr);
2553		}
2554	debugf("mDNS_Reconfirm_internal:%6ld ticks to go for %s %p",
2555		RRExpireTime(rr) - m->timenow, CRDisplayString(m, rr), rr->CRActiveQuestion);
2556	return(mStatus_NoError);
2557	}
2558
2559#define MaxQuestionInterval         (3600 * mDNSPlatformOneSecond)
2560
2561// BuildQuestion puts a question into a DNS Query packet and if successful, updates the value of queryptr.
2562// It also appends to the list of known answer records that need to be included,
2563// and updates the forcast for the size of the known answer section.
2564mDNSlocal mDNSBool BuildQuestion(mDNS *const m, DNSMessage *query, mDNSu8 **queryptr, DNSQuestion *q,
2565	CacheRecord ***kalistptrptr, mDNSu32 *answerforecast)
2566	{
2567	mDNSBool ucast = (q->LargeAnswers || q->RequestUnicast) && m->CanReceiveUnicastOn5353;
2568	mDNSu16 ucbit = (mDNSu16)(ucast ? kDNSQClass_UnicastResponse : 0);
2569	const mDNSu8 *const limit = query->data + NormalMaxDNSMessageData;
2570	mDNSu8 *newptr = putQuestion(query, *queryptr, limit - *answerforecast, &q->qname, q->qtype, (mDNSu16)(q->qclass | ucbit));
2571	if (!newptr)
2572		{
2573		debugf("BuildQuestion: No more space in this packet for question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
2574		return(mDNSfalse);
2575		}
2576	else
2577		{
2578		mDNSu32 forecast = *answerforecast;
2579		const mDNSu32 slot = HashSlot(&q->qname);
2580		const CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
2581		CacheRecord *rr;
2582		CacheRecord **ka = *kalistptrptr;	// Make a working copy of the pointer we're going to update
2583
2584		for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)				// If we have a resource record in our cache,
2585			if (rr->resrec.InterfaceID == q->SendQNow &&					// received on this interface
2586				!(rr->resrec.RecordType & kDNSRecordTypeUniqueMask) &&		// which is a shared (i.e. not unique) record type
2587				rr->NextInKAList == mDNSNULL && ka != &rr->NextInKAList &&	// which is not already in the known answer list
2588				rr->resrec.rdlength <= SmallRecordLimit &&					// which is small enough to sensibly fit in the packet
2589				SameNameRecordAnswersQuestion(&rr->resrec, q) &&			// which answers our question
2590				rr->TimeRcvd + TicksTTL(rr)/2 - m->timenow >				// and its half-way-to-expiry time is at least 1 second away
2591												mDNSPlatformOneSecond)		// (also ensures we never include goodbye records with TTL=1)
2592				{
2593				// We don't want to include unique records in the Known Answer section. The Known Answer section
2594				// is intended to suppress floods of shared-record replies from many other devices on the network.
2595				// That concept really does not apply to unique records, and indeed if we do send a query for
2596				// which we have a unique record already in our cache, then including that unique record as a
2597				// Known Answer, so as to suppress the only answer we were expecting to get, makes little sense.
2598
2599				*ka = rr;	// Link this record into our known answer chain
2600				ka = &rr->NextInKAList;
2601				// We forecast: compressed name (2) type (2) class (2) TTL (4) rdlength (2) rdata (n)
2602				forecast += 12 + rr->resrec.rdestimate;
2603				// If we're trying to put more than one question in this packet, and it doesn't fit
2604				// then undo that last question and try again next time
2605				if (query->h.numQuestions > 1 && newptr + forecast >= limit)
2606					{
2607					debugf("BuildQuestion: Retracting question %##s (%s) new forecast total %d",
2608						q->qname.c, DNSTypeName(q->qtype), newptr + forecast - query->data);
2609					query->h.numQuestions--;
2610					ka = *kalistptrptr;		// Go back to where we started and retract these answer records
2611					while (*ka) { CacheRecord *c = *ka; *ka = mDNSNULL; ka = &c->NextInKAList; }
2612					return(mDNSfalse);		// Return false, so we'll try again in the next packet
2613					}
2614				}
2615
2616		// Success! Update our state pointers, increment UnansweredQueries as appropriate, and return
2617		*queryptr        = newptr;				// Update the packet pointer
2618		*answerforecast  = forecast;			// Update the forecast
2619		*kalistptrptr    = ka;					// Update the known answer list pointer
2620		if (ucast) q->ExpectUnicastResp = NonZeroTime(m->timenow);
2621
2622		for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)				// For every resource record in our cache,
2623			if (rr->resrec.InterfaceID == q->SendQNow &&					// received on this interface
2624				rr->NextInKAList == mDNSNULL && ka != &rr->NextInKAList &&	// which is not in the known answer list
2625				SameNameRecordAnswersQuestion(&rr->resrec, q))				// which answers our question
2626					{
2627					rr->UnansweredQueries++;								// indicate that we're expecting a response
2628					rr->LastUnansweredTime = m->timenow;
2629					SetNextCacheCheckTimeForRecord(m, rr);
2630					}
2631
2632		return(mDNStrue);
2633		}
2634	}
2635
2636// When we have a query looking for a specified name, but there appear to be no answers with
2637// that name, ReconfirmAntecedents() is called with depth=0 to start the reconfirmation process
2638// for any records in our cache that reference the given name (e.g. PTR and SRV records).
2639// For any such cache record we find, we also recursively call ReconfirmAntecedents() for *its* name.
2640// We increment depth each time we recurse, to guard against possible infinite loops, with a limit of 5.
2641// A typical reconfirmation scenario might go like this:
2642// Depth 0: Name "myhost.local" has no address records
2643// Depth 1: SRV "My Service._example._tcp.local." refers to "myhost.local"; may be stale
2644// Depth 2: PTR "_example._tcp.local." refers to "My Service"; may be stale
2645// Depth 3: PTR "_services._dns-sd._udp.local." refers to "_example._tcp.local."; may be stale
2646// Currently depths 4 and 5 are not expected to occur; if we did get to depth 5 we'd reconfim any records we
2647// found referring to the given name, but not recursively descend any further reconfirm *their* antecedents.
2648mDNSlocal void ReconfirmAntecedents(mDNS *const m, const domainname *const name, const mDNSu32 namehash, const int depth)
2649	{
2650	mDNSu32 slot;
2651	CacheGroup *cg;
2652	CacheRecord *cr;
2653	debugf("ReconfirmAntecedents (depth=%d) for %##s", depth, name->c);
2654	FORALL_CACHERECORDS(slot, cg, cr)
2655		{
2656		domainname *crtarget = GetRRDomainNameTarget(&cr->resrec);
2657		if (crtarget && cr->resrec.rdatahash == namehash && SameDomainName(crtarget, name))
2658			{
2659			LogInfo("ReconfirmAntecedents: Reconfirming (depth=%d) %s", depth, CRDisplayString(m, cr));
2660			mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForNoAnswer);
2661			if (depth < 5) ReconfirmAntecedents(m, cr->resrec.name, cr->resrec.namehash, depth+1);
2662			}
2663		}
2664	}
2665
2666// If we get no answer for a AAAA query, then before doing an automatic implicit ReconfirmAntecedents
2667// we check if we have an address record for the same name. If we do have an IPv4 address for a given
2668// name but not an IPv6 address, that's okay (it just means the device doesn't do IPv6) so the failure
2669// to get a AAAA response is not grounds to doubt the PTR/SRV chain that lead us to that name.
2670mDNSlocal const CacheRecord *CacheHasAddressTypeForName(mDNS *const m, const domainname *const name, const mDNSu32 namehash)
2671	{
2672	CacheGroup *const cg = CacheGroupForName(m, HashSlot(name), namehash, name);
2673	const CacheRecord *cr = cg ? cg->members : mDNSNULL;
2674	while (cr && !RRTypeIsAddressType(cr->resrec.rrtype)) cr=cr->next;
2675	return(cr);
2676	}
2677
2678mDNSlocal const CacheRecord *FindSPSInCache1(mDNS *const m, const DNSQuestion *const q, const CacheRecord *const c0, const CacheRecord *const c1)
2679	{
2680	CacheGroup *const cg = CacheGroupForName(m, HashSlot(&q->qname), q->qnamehash, &q->qname);
2681	const CacheRecord *cr, *bestcr = mDNSNULL;
2682	mDNSu32 bestmetric = 1000000;
2683	for (cr = cg ? cg->members : mDNSNULL; cr; cr=cr->next)
2684		if (cr->resrec.rrtype == kDNSType_PTR && cr->resrec.rdlength >= 6)						// If record is PTR type, with long enough name,
2685			if (cr != c0 && cr != c1)															// that's not one we've seen before,
2686				if (SameNameRecordAnswersQuestion(&cr->resrec, q))								// and answers our browse query,
2687					if (!IdenticalSameNameRecord(&cr->resrec, &m->SPSRecords.RR_PTR.resrec))	// and is not our own advertised service...
2688						{
2689						mDNSu32 metric = SPSMetric(cr->resrec.rdata->u.name.c);
2690						if (bestmetric > metric) { bestmetric = metric; bestcr = cr; }
2691						}
2692	return(bestcr);
2693	}
2694
2695// Finds the three best Sleep Proxies we currently have in our cache
2696mDNSexport void FindSPSInCache(mDNS *const m, const DNSQuestion *const q, const CacheRecord *sps[3])
2697	{
2698	sps[0] =                      FindSPSInCache1(m, q, mDNSNULL, mDNSNULL);
2699	sps[1] = !sps[0] ? mDNSNULL : FindSPSInCache1(m, q, sps[0],   mDNSNULL);
2700	sps[2] = !sps[1] ? mDNSNULL : FindSPSInCache1(m, q, sps[0],   sps[1]);
2701	}
2702
2703// Only DupSuppressInfos newer than the specified 'time' are allowed to remain active
2704mDNSlocal void ExpireDupSuppressInfo(DupSuppressInfo ds[DupSuppressInfoSize], mDNSs32 time)
2705	{
2706	int i;
2707	for (i=0; i<DupSuppressInfoSize; i++) if (ds[i].Time - time < 0) ds[i].InterfaceID = mDNSNULL;
2708	}
2709
2710mDNSlocal void ExpireDupSuppressInfoOnInterface(DupSuppressInfo ds[DupSuppressInfoSize], mDNSs32 time, mDNSInterfaceID InterfaceID)
2711	{
2712	int i;
2713	for (i=0; i<DupSuppressInfoSize; i++) if (ds[i].InterfaceID == InterfaceID && ds[i].Time - time < 0) ds[i].InterfaceID = mDNSNULL;
2714	}
2715
2716mDNSlocal mDNSBool SuppressOnThisInterface(const DupSuppressInfo ds[DupSuppressInfoSize], const NetworkInterfaceInfo * const intf)
2717	{
2718	int i;
2719	mDNSBool v4 = !intf->IPv4Available;		// If this interface doesn't do v4, we don't need to find a v4 duplicate of this query
2720	mDNSBool v6 = !intf->IPv6Available;		// If this interface doesn't do v6, we don't need to find a v6 duplicate of this query
2721	for (i=0; i<DupSuppressInfoSize; i++)
2722		if (ds[i].InterfaceID == intf->InterfaceID)
2723			{
2724			if      (ds[i].Type == mDNSAddrType_IPv4) v4 = mDNStrue;
2725			else if (ds[i].Type == mDNSAddrType_IPv6) v6 = mDNStrue;
2726			if (v4 && v6) return(mDNStrue);
2727			}
2728	return(mDNSfalse);
2729	}
2730
2731mDNSlocal int RecordDupSuppressInfo(DupSuppressInfo ds[DupSuppressInfoSize], mDNSs32 Time, mDNSInterfaceID InterfaceID, mDNSs32 Type)
2732	{
2733	int i, j;
2734
2735	// See if we have this one in our list somewhere already
2736	for (i=0; i<DupSuppressInfoSize; i++) if (ds[i].InterfaceID == InterfaceID && ds[i].Type == Type) break;
2737
2738	// If not, find a slot we can re-use
2739	if (i >= DupSuppressInfoSize)
2740		{
2741		i = 0;
2742		for (j=1; j<DupSuppressInfoSize && ds[i].InterfaceID; j++)
2743			if (!ds[j].InterfaceID || ds[j].Time - ds[i].Time < 0)
2744				i = j;
2745		}
2746
2747	// Record the info about this query we saw
2748	ds[i].Time        = Time;
2749	ds[i].InterfaceID = InterfaceID;
2750	ds[i].Type        = Type;
2751
2752	return(i);
2753	}
2754
2755mDNSlocal void mDNSSendWakeOnResolve(mDNS *const m, DNSQuestion *q)
2756	{
2757	int len, i, cnt;
2758	mDNSInterfaceID InterfaceID = q->InterfaceID;
2759	domainname *d = &q->qname;
2760
2761	// We can't send magic packets without knowing which interface to send it on.
2762	if (InterfaceID == mDNSInterface_Any || InterfaceID == mDNSInterface_LocalOnly || InterfaceID == mDNSInterface_P2P)
2763		{
2764		LogMsg("mDNSSendWakeOnResolve: ERROR!! Invalid InterfaceID %p for question %##s", InterfaceID, q->qname.c);
2765		return;
2766		}
2767
2768	// Split MAC@IPAddress and pass them separately
2769	len = d->c[0];
2770	i = 1;
2771	cnt = 0;
2772	for (i = 1; i < len; i++)
2773		{
2774		if (d->c[i] == '@')
2775			{
2776			char EthAddr[18];	// ethernet adddress : 12 bytes + 5 ":" + 1 NULL byte
2777			char IPAddr[47];    // Max IP address len: 46 bytes (IPv6) + 1 NULL byte
2778			if (cnt != 5)
2779				{
2780				LogMsg("mDNSSendWakeOnResolve: ERROR!! Malformed Ethernet address %##s, cnt %d", q->qname.c, cnt);
2781				return;
2782				}
2783			if ((i - 1) > (int) (sizeof(EthAddr) - 1))
2784				{
2785				LogMsg("mDNSSendWakeOnResolve: ERROR!! Malformed Ethernet address %##s, length %d", q->qname.c, i - 1);
2786				return;
2787				}
2788			if ((len - i) > (int)(sizeof(IPAddr) - 1))
2789				{
2790				LogMsg("mDNSSendWakeOnResolve: ERROR!! Malformed IP address %##s, length %d", q->qname.c, len - i);
2791				return;
2792				}
2793			mDNSPlatformMemCopy(EthAddr, &d->c[1], i - 1);
2794			EthAddr[i - 1] = 0;
2795			mDNSPlatformMemCopy(IPAddr, &d->c[i + 1], len - i);
2796			IPAddr[len - i] = 0;
2797			mDNSPlatformSendWakeupPacket(m, InterfaceID, EthAddr, IPAddr, InitialWakeOnResolveCount - q->WakeOnResolveCount);
2798			return;
2799			}
2800		else if (d->c[i] == ':')
2801			cnt++;
2802		}
2803	LogMsg("mDNSSendWakeOnResolve: ERROR!! Malformed WakeOnResolve name %##s", q->qname.c);
2804	}
2805
2806
2807mDNSlocal mDNSBool AccelerateThisQuery(mDNS *const m, DNSQuestion *q)
2808	{
2809	// If more than 90% of the way to the query time, we should unconditionally accelerate it
2810	if (TimeToSendThisQuestion(q, m->timenow + q->ThisQInterval/10))
2811		return(mDNStrue);
2812
2813	// If half-way to next scheduled query time, only accelerate if it will add less than 512 bytes to the packet
2814	if (TimeToSendThisQuestion(q, m->timenow + q->ThisQInterval/2))
2815		{
2816		// We forecast: qname (n) type (2) class (2)
2817		mDNSu32 forecast = (mDNSu32)DomainNameLength(&q->qname) + 4;
2818		const mDNSu32 slot = HashSlot(&q->qname);
2819		const CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
2820		const CacheRecord *rr;
2821		for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)				// If we have a resource record in our cache,
2822			if (rr->resrec.rdlength <= SmallRecordLimit &&					// which is small enough to sensibly fit in the packet
2823				SameNameRecordAnswersQuestion(&rr->resrec, q) &&			// which answers our question
2824				rr->TimeRcvd + TicksTTL(rr)/2 - m->timenow >= 0 &&			// and it is less than half-way to expiry
2825				rr->NextRequiredQuery - (m->timenow + q->ThisQInterval) > 0)// and we'll ask at least once again before NextRequiredQuery
2826				{
2827				// We forecast: compressed name (2) type (2) class (2) TTL (4) rdlength (2) rdata (n)
2828				forecast += 12 + rr->resrec.rdestimate;
2829				if (forecast >= 512) return(mDNSfalse);	// If this would add 512 bytes or more to the packet, don't accelerate
2830				}
2831		return(mDNStrue);
2832		}
2833
2834	return(mDNSfalse);
2835	}
2836
2837// How Standard Queries are generated:
2838// 1. The Question Section contains the question
2839// 2. The Additional Section contains answers we already know, to suppress duplicate responses
2840
2841// How Probe Queries are generated:
2842// 1. The Question Section contains queries for the name we intend to use, with QType=ANY because
2843// if some other host is already using *any* records with this name, we want to know about it.
2844// 2. The Authority Section contains the proposed values we intend to use for one or more
2845// of our records with that name (analogous to the Update section of DNS Update packets)
2846// because if some other host is probing at the same time, we each want to know what the other is
2847// planning, in order to apply the tie-breaking rule to see who gets to use the name and who doesn't.
2848
2849mDNSlocal void SendQueries(mDNS *const m)
2850	{
2851	mDNSu32 slot;
2852	CacheGroup *cg;
2853	CacheRecord *cr;
2854	AuthRecord *ar;
2855	int pktcount = 0;
2856	DNSQuestion *q;
2857	// For explanation of maxExistingQuestionInterval logic, see comments for maxExistingAnnounceInterval
2858	mDNSs32 maxExistingQuestionInterval = 0;
2859	const NetworkInterfaceInfo *intf = GetFirstActiveInterface(m->HostInterfaces);
2860	CacheRecord *KnownAnswerList = mDNSNULL;
2861
2862	// 1. If time for a query, work out what we need to do
2863
2864	// We're expecting to send a query anyway, so see if any expiring cache records are close enough
2865	// to their NextRequiredQuery to be worth batching them together with this one
2866	FORALL_CACHERECORDS(slot, cg, cr)
2867		if (cr->CRActiveQuestion && cr->UnansweredQueries < MaxUnansweredQueries)
2868			if (m->timenow + TicksTTL(cr)/50 - cr->NextRequiredQuery >= 0)
2869				{
2870				debugf("Sending %d%% cache expiration query for %s", 80 + 5 * cr->UnansweredQueries, CRDisplayString(m, cr));
2871				q = cr->CRActiveQuestion;
2872				ExpireDupSuppressInfoOnInterface(q->DupSuppress, m->timenow - TicksTTL(cr)/20, cr->resrec.InterfaceID);
2873				// For uDNS queries (TargetQID non-zero) we adjust LastQTime,
2874				// and bump UnansweredQueries so that we don't spin trying to send the same cache expiration query repeatedly
2875				if      (q->Target.type)                        q->SendQNow = mDNSInterfaceMark;	// If targeted query, mark it
2876				else if (!mDNSOpaque16IsZero(q->TargetQID))     { q->LastQTime = m->timenow - q->ThisQInterval; cr->UnansweredQueries++; }
2877				else if (q->SendQNow == mDNSNULL)               q->SendQNow = cr->resrec.InterfaceID;
2878				else if (q->SendQNow != cr->resrec.InterfaceID) q->SendQNow = mDNSInterfaceMark;
2879				}
2880
2881	// Scan our list of questions to see which:
2882	//     *WideArea*  queries need to be sent
2883	//     *unicast*   queries need to be sent
2884	//     *multicast* queries we're definitely going to send
2885	if (m->CurrentQuestion)
2886		LogMsg("SendQueries ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
2887	m->CurrentQuestion = m->Questions;
2888	while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
2889		{
2890		q = m->CurrentQuestion;
2891		if (q->Target.type && (q->SendQNow || TimeToSendThisQuestion(q, m->timenow)))
2892			{
2893			mDNSu8       *qptr        = m->omsg.data;
2894			const mDNSu8 *const limit = m->omsg.data + sizeof(m->omsg.data);
2895
2896			// If we fail to get a new on-demand socket (should only happen cases of the most extreme resource exhaustion), we'll try again next time
2897			if (!q->LocalSocket) q->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
2898			if (q->LocalSocket)
2899				{
2900				InitializeDNSMessage(&m->omsg.h, q->TargetQID, QueryFlags);
2901				qptr = putQuestion(&m->omsg, qptr, limit, &q->qname, q->qtype, q->qclass);
2902				mDNSSendDNSMessage(m, &m->omsg, qptr, mDNSInterface_Any, q->LocalSocket, &q->Target, q->TargetPort, mDNSNULL, mDNSNULL);
2903				q->ThisQInterval    *= QuestionIntervalStep;
2904				}
2905			if (q->ThisQInterval > MaxQuestionInterval)
2906				q->ThisQInterval = MaxQuestionInterval;
2907			q->LastQTime         = m->timenow;
2908			q->LastQTxTime       = m->timenow;
2909			q->RecentAnswerPkts  = 0;
2910			q->SendQNow          = mDNSNULL;
2911			q->ExpectUnicastResp = NonZeroTime(m->timenow);
2912			}
2913		else if (mDNSOpaque16IsZero(q->TargetQID) && !q->Target.type && TimeToSendThisQuestion(q, m->timenow))
2914			{
2915			//LogInfo("Time to send %##s (%s) %d", q->qname.c, DNSTypeName(q->qtype), m->timenow - NextQSendTime(q));
2916			q->SendQNow = mDNSInterfaceMark;		// Mark this question for sending on all interfaces
2917			if (maxExistingQuestionInterval < q->ThisQInterval)
2918				maxExistingQuestionInterval = q->ThisQInterval;
2919			}
2920		// If m->CurrentQuestion wasn't modified out from under us, advance it now
2921		// We can't do this at the start of the loop because uDNS_CheckCurrentQuestion() depends on having
2922		// m->CurrentQuestion point to the right question
2923		if (q == m->CurrentQuestion) m->CurrentQuestion = m->CurrentQuestion->next;
2924		}
2925	while (m->CurrentQuestion)
2926		{
2927		LogInfo("SendQueries question loop 1: Skipping NewQuestion %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
2928		m->CurrentQuestion = m->CurrentQuestion->next;
2929		}
2930	m->CurrentQuestion = mDNSNULL;
2931
2932	// Scan our list of questions
2933	// (a) to see if there are any more that are worth accelerating, and
2934	// (b) to update the state variables for *all* the questions we're going to send
2935	// Note: Don't set NextScheduledQuery until here, because uDNS_CheckCurrentQuestion in the loop above can add new questions to the list,
2936	// which causes NextScheduledQuery to get (incorrectly) set to m->timenow. Setting it here is the right place, because the very
2937	// next thing we do is scan the list and call SetNextQueryTime() for every question we find, so we know we end up with the right value.
2938	m->NextScheduledQuery = m->timenow + 0x78000000;
2939	for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
2940		{
2941		if (mDNSOpaque16IsZero(q->TargetQID) && (q->SendQNow ||
2942			(!q->Target.type && ActiveQuestion(q) && q->ThisQInterval <= maxExistingQuestionInterval && AccelerateThisQuery(m,q))))
2943			{
2944			// If at least halfway to next query time, advance to next interval
2945			// If less than halfway to next query time, then
2946			// treat this as logically a repeat of the last transmission, without advancing the interval
2947			if (m->timenow - (q->LastQTime + (q->ThisQInterval/2)) >= 0)
2948				{
2949				//LogInfo("Accelerating %##s (%s) %d", q->qname.c, DNSTypeName(q->qtype), m->timenow - NextQSendTime(q));
2950				q->SendQNow = mDNSInterfaceMark;	// Mark this question for sending on all interfaces
2951				debugf("SendQueries: %##s (%s) next interval %d seconds RequestUnicast = %d",
2952					q->qname.c, DNSTypeName(q->qtype), q->ThisQInterval / InitialQuestionInterval, q->RequestUnicast);
2953				q->ThisQInterval *= QuestionIntervalStep;
2954				if (q->ThisQInterval > MaxQuestionInterval)
2955					q->ThisQInterval = MaxQuestionInterval;
2956				else if (q->CurrentAnswers == 0 && q->ThisQInterval == InitialQuestionInterval * QuestionIntervalStep3 && !q->RequestUnicast &&
2957						!(RRTypeIsAddressType(q->qtype) && CacheHasAddressTypeForName(m, &q->qname, q->qnamehash)))
2958					{
2959					// Generally don't need to log this.
2960					// It's not especially noteworthy if a query finds no results -- this usually happens for domain
2961					// enumeration queries in the LL subdomain (e.g. "db._dns-sd._udp.0.0.254.169.in-addr.arpa")
2962					// and when there simply happen to be no instances of the service the client is looking
2963					// for (e.g. iTunes is set to look for RAOP devices, and the current network has none).
2964					debugf("SendQueries: Zero current answers for %##s (%s); will reconfirm antecedents",
2965						q->qname.c, DNSTypeName(q->qtype));
2966					// Sending third query, and no answers yet; time to begin doubting the source
2967					ReconfirmAntecedents(m, &q->qname, q->qnamehash, 0);
2968					}
2969				}
2970
2971			// Mark for sending. (If no active interfaces, then don't even try.)
2972			q->SendOnAll = (q->SendQNow == mDNSInterfaceMark);
2973			if (q->SendOnAll)
2974				{
2975				q->SendQNow  = !intf ? mDNSNULL : (q->InterfaceID) ? q->InterfaceID : intf->InterfaceID;
2976				q->LastQTime = m->timenow;
2977				}
2978
2979			// If we recorded a duplicate suppression for this question less than half an interval ago,
2980			// then we consider it recent enough that we don't need to do an identical query ourselves.
2981			ExpireDupSuppressInfo(q->DupSuppress, m->timenow - q->ThisQInterval/2);
2982
2983			q->LastQTxTime      = m->timenow;
2984			q->RecentAnswerPkts = 0;
2985			if (q->RequestUnicast) q->RequestUnicast--;
2986			}
2987		// For all questions (not just the ones we're sending) check what the next scheduled event will be
2988		// We don't need to consider NewQuestions here because for those we'll set m->NextScheduledQuery in AnswerNewQuestion
2989		SetNextQueryTime(m,q);
2990		}
2991
2992	// 2. Scan our authoritative RR list to see what probes we might need to send
2993
2994	m->NextScheduledProbe = m->timenow + 0x78000000;
2995
2996	if (m->CurrentRecord)
2997		LogMsg("SendQueries ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
2998	m->CurrentRecord = m->ResourceRecords;
2999	while (m->CurrentRecord)
3000		{
3001		ar = m->CurrentRecord;
3002		m->CurrentRecord = ar->next;
3003		if (!AuthRecord_uDNS(ar) && ar->resrec.RecordType == kDNSRecordTypeUnique)	// For all records that are still probing...
3004			{
3005			// 1. If it's not reached its probe time, just make sure we update m->NextScheduledProbe correctly
3006			if (m->timenow - (ar->LastAPTime + ar->ThisAPInterval) < 0)
3007				{
3008				SetNextAnnounceProbeTime(m, ar);
3009				}
3010			// 2. else, if it has reached its probe time, mark it for sending and then update m->NextScheduledProbe correctly
3011			else if (ar->ProbeCount)
3012				{
3013				if (ar->AddressProxy.type == mDNSAddrType_IPv4)
3014					{
3015					LogSPS("SendQueries ARP Probe %d %s %s", ar->ProbeCount, InterfaceNameForID(m, ar->resrec.InterfaceID), ARDisplayString(m,ar));
3016					SendARP(m, 1, ar, &zerov4Addr, &zeroEthAddr, &ar->AddressProxy.ip.v4, &ar->WakeUp.IMAC);
3017					}
3018				else if (ar->AddressProxy.type == mDNSAddrType_IPv6)
3019					{
3020					LogSPS("SendQueries NDP Probe %d %s %s", ar->ProbeCount, InterfaceNameForID(m, ar->resrec.InterfaceID), ARDisplayString(m,ar));
3021					// IPv6 source = zero
3022					// No target hardware address
3023					// IPv6 target address is address we're probing
3024					// Ethernet destination address is Ethernet interface address of the Sleep Proxy client we're probing
3025					SendNDP(m, NDP_Sol, 0, ar, &zerov6Addr, mDNSNULL, &ar->AddressProxy.ip.v6, &ar->WakeUp.IMAC);
3026					}
3027				// Mark for sending. (If no active interfaces, then don't even try.)
3028				ar->SendRNow   = (!intf || ar->WakeUp.HMAC.l[0]) ? mDNSNULL : ar->resrec.InterfaceID ? ar->resrec.InterfaceID : intf->InterfaceID;
3029				ar->LastAPTime = m->timenow;
3030				// When we have a late conflict that resets a record to probing state we use a special marker value greater
3031				// than DefaultProbeCountForTypeUnique. Here we detect that state and reset ar->ProbeCount back to the right value.
3032				if (ar->ProbeCount > DefaultProbeCountForTypeUnique)
3033					ar->ProbeCount = DefaultProbeCountForTypeUnique;
3034				ar->ProbeCount--;
3035				SetNextAnnounceProbeTime(m, ar);
3036				if (ar->ProbeCount == 0)
3037					{
3038					// If this is the last probe for this record, then see if we have any matching records
3039					// on our duplicate list which should similarly have their ProbeCount cleared to zero...
3040					AuthRecord *r2;
3041					for (r2 = m->DuplicateRecords; r2; r2=r2->next)
3042						if (r2->resrec.RecordType == kDNSRecordTypeUnique && RecordIsLocalDuplicate(r2, ar))
3043							r2->ProbeCount = 0;
3044					// ... then acknowledge this record to the client.
3045					// We do this optimistically, just as we're about to send the third probe.
3046					// This helps clients that both advertise and browse, and want to filter themselves
3047					// from the browse results list, because it helps ensure that the registration
3048					// confirmation will be delivered 1/4 second *before* the browse "add" event.
3049					// A potential downside is that we could deliver a registration confirmation and then find out
3050					// moments later that there's a name conflict, but applications have to be prepared to handle
3051					// late conflicts anyway (e.g. on connection of network cable, etc.), so this is nothing new.
3052					if (!ar->Acknowledged) AcknowledgeRecord(m, ar);
3053					}
3054				}
3055			// else, if it has now finished probing, move it to state Verified,
3056			// and update m->NextScheduledResponse so it will be announced
3057			else
3058				{
3059				if (!ar->Acknowledged) AcknowledgeRecord(m, ar);	// Defensive, just in case it got missed somehow
3060				ar->resrec.RecordType     = kDNSRecordTypeVerified;
3061				ar->ThisAPInterval = DefaultAnnounceIntervalForTypeUnique;
3062				ar->LastAPTime     = m->timenow - DefaultAnnounceIntervalForTypeUnique;
3063				SetNextAnnounceProbeTime(m, ar);
3064				}
3065			}
3066		}
3067	m->CurrentRecord = m->DuplicateRecords;
3068	while (m->CurrentRecord)
3069		{
3070		ar = m->CurrentRecord;
3071		m->CurrentRecord = ar->next;
3072		if (ar->resrec.RecordType == kDNSRecordTypeUnique && ar->ProbeCount == 0 && !ar->Acknowledged)
3073			AcknowledgeRecord(m, ar);
3074		}
3075
3076	// 3. Now we know which queries and probes we're sending,
3077	// go through our interface list sending the appropriate queries on each interface
3078	while (intf)
3079		{
3080		const int OwnerRecordSpace = (m->AnnounceOwner && intf->MAC.l[0]) ? DNSOpt_Header_Space + DNSOpt_Owner_Space(&m->PrimaryMAC, &intf->MAC) : 0;
3081		mDNSu8 *queryptr = m->omsg.data;
3082		InitializeDNSMessage(&m->omsg.h, zeroID, QueryFlags);
3083		if (KnownAnswerList) verbosedebugf("SendQueries:   KnownAnswerList set... Will continue from previous packet");
3084		if (!KnownAnswerList)
3085			{
3086			// Start a new known-answer list
3087			CacheRecord **kalistptr = &KnownAnswerList;
3088			mDNSu32 answerforecast = OwnerRecordSpace;		// We start by assuming we'll need at least enough space to put the Owner Option
3089
3090			// Put query questions in this packet
3091			for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
3092				{
3093				if (mDNSOpaque16IsZero(q->TargetQID) && (q->SendQNow == intf->InterfaceID))
3094					{
3095					debugf("SendQueries: %s question for %##s (%s) at %d forecast total %d",
3096						SuppressOnThisInterface(q->DupSuppress, intf) ? "Suppressing" : "Putting    ",
3097						q->qname.c, DNSTypeName(q->qtype), queryptr - m->omsg.data, queryptr + answerforecast - m->omsg.data);
3098
3099					// If we're suppressing this question, or we successfully put it, update its SendQNow state
3100					if (SuppressOnThisInterface(q->DupSuppress, intf) ||
3101						BuildQuestion(m, &m->omsg, &queryptr, q, &kalistptr, &answerforecast))
3102						{
3103						q->SendQNow = (q->InterfaceID || !q->SendOnAll) ? mDNSNULL : GetNextActiveInterfaceID(intf);
3104						if (q->WakeOnResolveCount)
3105							{
3106							mDNSSendWakeOnResolve(m, q);
3107							q->WakeOnResolveCount--;
3108							}
3109						}
3110					}
3111				}
3112
3113			// Put probe questions in this packet
3114			for (ar = m->ResourceRecords; ar; ar=ar->next)
3115				if (ar->SendRNow == intf->InterfaceID)
3116					{
3117					mDNSBool ucast = (ar->ProbeCount >= DefaultProbeCountForTypeUnique-1) && m->CanReceiveUnicastOn5353;
3118					mDNSu16 ucbit = (mDNSu16)(ucast ? kDNSQClass_UnicastResponse : 0);
3119					const mDNSu8 *const limit = m->omsg.data + (m->omsg.h.numQuestions ? NormalMaxDNSMessageData : AbsoluteMaxDNSMessageData);
3120					// We forecast: compressed name (2) type (2) class (2) TTL (4) rdlength (2) rdata (n)
3121					mDNSu32 forecast = answerforecast + 12 + ar->resrec.rdestimate;
3122					mDNSu8 *newptr = putQuestion(&m->omsg, queryptr, limit - forecast, ar->resrec.name, kDNSQType_ANY, (mDNSu16)(ar->resrec.rrclass | ucbit));
3123					if (newptr)
3124						{
3125						queryptr       = newptr;
3126						answerforecast = forecast;
3127						ar->SendRNow = (ar->resrec.InterfaceID) ? mDNSNULL : GetNextActiveInterfaceID(intf);
3128						ar->IncludeInProbe = mDNStrue;
3129						verbosedebugf("SendQueries:   Put Question %##s (%s) probecount %d",
3130							ar->resrec.name->c, DNSTypeName(ar->resrec.rrtype), ar->ProbeCount);
3131						}
3132					}
3133			}
3134
3135		// Put our known answer list (either new one from this question or questions, or remainder of old one from last time)
3136		while (KnownAnswerList)
3137			{
3138			CacheRecord *ka = KnownAnswerList;
3139			mDNSu32 SecsSinceRcvd = ((mDNSu32)(m->timenow - ka->TimeRcvd)) / mDNSPlatformOneSecond;
3140			mDNSu8 *newptr = PutResourceRecordTTLWithLimit(&m->omsg, queryptr, &m->omsg.h.numAnswers,
3141				&ka->resrec, ka->resrec.rroriginalttl - SecsSinceRcvd, m->omsg.data + NormalMaxDNSMessageData - OwnerRecordSpace);
3142			if (newptr)
3143				{
3144				verbosedebugf("SendQueries:   Put %##s (%s) at %d - %d",
3145					ka->resrec.name->c, DNSTypeName(ka->resrec.rrtype), queryptr - m->omsg.data, newptr - m->omsg.data);
3146				queryptr = newptr;
3147				KnownAnswerList = ka->NextInKAList;
3148				ka->NextInKAList = mDNSNULL;
3149				}
3150			else
3151				{
3152				// If we ran out of space and we have more than one question in the packet, that's an error --
3153				// we shouldn't have put more than one question if there was a risk of us running out of space.
3154				if (m->omsg.h.numQuestions > 1)
3155					LogMsg("SendQueries:   Put %d answers; No more space for known answers", m->omsg.h.numAnswers);
3156				m->omsg.h.flags.b[0] |= kDNSFlag0_TC;
3157				break;
3158				}
3159			}
3160
3161		for (ar = m->ResourceRecords; ar; ar=ar->next)
3162			if (ar->IncludeInProbe)
3163				{
3164				mDNSu8 *newptr = PutResourceRecord(&m->omsg, queryptr, &m->omsg.h.numAuthorities, &ar->resrec);
3165				ar->IncludeInProbe = mDNSfalse;
3166				if (newptr) queryptr = newptr;
3167				else LogMsg("SendQueries:   How did we fail to have space for the Update record %s", ARDisplayString(m,ar));
3168				}
3169
3170		if (queryptr > m->omsg.data)
3171			{
3172			if (OwnerRecordSpace)
3173				{
3174				AuthRecord opt;
3175				mDNS_SetupResourceRecord(&opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
3176				opt.resrec.rrclass    = NormalMaxDNSMessageData;
3177				opt.resrec.rdlength   = sizeof(rdataOPT);	// One option in this OPT record
3178				opt.resrec.rdestimate = sizeof(rdataOPT);
3179				SetupOwnerOpt(m, intf, &opt.resrec.rdata->u.opt[0]);
3180				LogSPS("SendQueries putting %s", ARDisplayString(m, &opt));
3181				queryptr = PutResourceRecordTTLWithLimit(&m->omsg, queryptr, &m->omsg.h.numAdditionals,
3182					&opt.resrec, opt.resrec.rroriginalttl, m->omsg.data + AbsoluteMaxDNSMessageData);
3183				if (!queryptr)
3184					LogMsg("SendQueries: How did we fail to have space for the OPT record (%d/%d/%d/%d) %s",
3185						m->omsg.h.numQuestions, m->omsg.h.numAnswers, m->omsg.h.numAuthorities, m->omsg.h.numAdditionals, ARDisplayString(m, &opt));
3186				if (queryptr > m->omsg.data + NormalMaxDNSMessageData)
3187					if (m->omsg.h.numQuestions != 1 || m->omsg.h.numAnswers != 0 || m->omsg.h.numAuthorities != 1 || m->omsg.h.numAdditionals != 1)
3188						LogMsg("SendQueries: Why did we generate oversized packet with OPT record %p %p %p (%d/%d/%d/%d) %s",
3189							m->omsg.data, m->omsg.data + NormalMaxDNSMessageData, queryptr,
3190							m->omsg.h.numQuestions, m->omsg.h.numAnswers, m->omsg.h.numAuthorities, m->omsg.h.numAdditionals, ARDisplayString(m, &opt));
3191				}
3192
3193			if ((m->omsg.h.flags.b[0] & kDNSFlag0_TC) && m->omsg.h.numQuestions > 1)
3194				LogMsg("SendQueries: Should not have more than one question (%d) in a truncated packet", m->omsg.h.numQuestions);
3195			debugf("SendQueries:   Sending %d Question%s %d Answer%s %d Update%s on %p",
3196				m->omsg.h.numQuestions,   m->omsg.h.numQuestions   == 1 ? "" : "s",
3197				m->omsg.h.numAnswers,     m->omsg.h.numAnswers     == 1 ? "" : "s",
3198				m->omsg.h.numAuthorities, m->omsg.h.numAuthorities == 1 ? "" : "s", intf->InterfaceID);
3199			if (intf->IPv4Available) mDNSSendDNSMessage(m, &m->omsg, queryptr, intf->InterfaceID, mDNSNULL, &AllDNSLinkGroup_v4, MulticastDNSPort, mDNSNULL, mDNSNULL);
3200			if (intf->IPv6Available) mDNSSendDNSMessage(m, &m->omsg, queryptr, intf->InterfaceID, mDNSNULL, &AllDNSLinkGroup_v6, MulticastDNSPort, mDNSNULL, mDNSNULL);
3201			if (!m->SuppressSending) m->SuppressSending = NonZeroTime(m->timenow + (mDNSPlatformOneSecond+9)/10);
3202			if (++pktcount >= 1000)
3203				{ LogMsg("SendQueries exceeded loop limit %d: giving up", pktcount); break; }
3204			// There might be more records left in the known answer list, or more questions to send
3205			// on this interface, so go around one more time and try again.
3206			}
3207		else	// Nothing more to send on this interface; go to next
3208			{
3209			const NetworkInterfaceInfo *next = GetFirstActiveInterface(intf->next);
3210			#if MDNS_DEBUGMSGS && 0
3211			const char *const msg = next ? "SendQueries:   Nothing more on %p; moving to %p" : "SendQueries:   Nothing more on %p";
3212			debugf(msg, intf, next);
3213			#endif
3214			intf = next;
3215			}
3216		}
3217
3218	// 4. Final housekeeping
3219
3220	// 4a. Debugging check: Make sure we announced all our records
3221	for (ar = m->ResourceRecords; ar; ar=ar->next)
3222		if (ar->SendRNow)
3223			{
3224			if (ar->ARType != AuthRecordLocalOnly && ar->ARType != AuthRecordP2P)
3225				LogMsg("SendQueries: No active interface %p to send probe: %p %s", ar->SendRNow, ar->resrec.InterfaceID, ARDisplayString(m, ar));
3226			ar->SendRNow = mDNSNULL;
3227			}
3228
3229	// 4b. When we have lingering cache records that we're keeping around for a few seconds in the hope
3230	// that their interface which went away might come back again, the logic will want to send queries
3231	// for those records, but we can't because their interface isn't here any more, so to keep the
3232	// state machine ticking over we just pretend we did so.
3233	// If the interface does not come back in time, the cache record will expire naturally
3234	FORALL_CACHERECORDS(slot, cg, cr)
3235		if (cr->CRActiveQuestion && cr->UnansweredQueries < MaxUnansweredQueries)
3236			if (m->timenow + TicksTTL(cr)/50 - cr->NextRequiredQuery >= 0)
3237				{
3238				cr->UnansweredQueries++;
3239				cr->CRActiveQuestion->SendQNow = mDNSNULL;
3240				SetNextCacheCheckTimeForRecord(m, cr);
3241				}
3242
3243	// 4c. Debugging check: Make sure we sent all our planned questions
3244	// Do this AFTER the lingering cache records check above, because that will prevent spurious warnings for questions
3245	// we legitimately couldn't send because the interface is no longer available
3246	for (q = m->Questions; q; q=q->next)
3247		if (q->SendQNow)
3248			{
3249			DNSQuestion *x;
3250			for (x = m->NewQuestions; x; x=x->next) if (x == q) break;	// Check if this question is a NewQuestion
3251			LogMsg("SendQueries: No active interface %p to send %s question: %p %##s (%s)", q->SendQNow, x ? "new" : "old", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
3252			q->SendQNow = mDNSNULL;
3253			}
3254	}
3255
3256mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAddr *EthAddr, mDNSOpaque48 *password)
3257	{
3258	int i, j;
3259	mDNSu8 *ptr = m->omsg.data;
3260	NetworkInterfaceInfo *intf = FirstInterfaceForID(m, InterfaceID);
3261	if (!intf) { LogMsg("SendARP: No interface with InterfaceID %p found", InterfaceID); return; }
3262
3263	// 0x00 Destination address
3264	for (i=0; i<6; i++) *ptr++ = EthAddr->b[i];
3265
3266	// 0x06 Source address (Note: Since we don't currently set the BIOCSHDRCMPLT option, BPF will fill in the real interface address for us)
3267	for (i=0; i<6; i++) *ptr++ = intf->MAC.b[0];
3268
3269	// 0x0C Ethertype (0x0842)
3270	*ptr++ = 0x08;
3271	*ptr++ = 0x42;
3272
3273	// 0x0E Wakeup sync sequence
3274	for (i=0; i<6; i++) *ptr++ = 0xFF;
3275
3276	// 0x14 Wakeup data
3277	for (j=0; j<16; j++) for (i=0; i<6; i++) *ptr++ = EthAddr->b[i];
3278
3279	// 0x74 Password
3280	for (i=0; i<6; i++) *ptr++ = password->b[i];
3281
3282	mDNSPlatformSendRawPacket(m->omsg.data, ptr, InterfaceID);
3283
3284	// For Ethernet switches that don't flood-foward packets with unknown unicast destination MAC addresses,
3285	// broadcast is the only reliable way to get a wakeup packet to the intended target machine.
3286	// For 802.11 WPA networks, where a sleeping target machine may have missed a broadcast/multicast
3287	// key rotation, unicast is the only way to get a wakeup packet to the intended target machine.
3288	// So, we send one of each, unicast first, then broadcast second.
3289	for (i=0; i<6; i++) m->omsg.data[i] = 0xFF;
3290	mDNSPlatformSendRawPacket(m->omsg.data, ptr, InterfaceID);
3291	}
3292
3293// ***************************************************************************
3294#if COMPILER_LIKES_PRAGMA_MARK
3295#pragma mark -
3296#pragma mark - RR List Management & Task Management
3297#endif
3298
3299// Note: AnswerCurrentQuestionWithResourceRecord can call a user callback, which may change the record list and/or question list.
3300// Any code walking either list must use the m->CurrentQuestion (and possibly m->CurrentRecord) mechanism to protect against this.
3301// In fact, to enforce this, the routine will *only* answer the question currently pointed to by m->CurrentQuestion,
3302// which will be auto-advanced (possibly to NULL) if the client callback cancels the question.
3303mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheRecord *const rr, const QC_result AddRecord)
3304	{
3305	DNSQuestion *const q = m->CurrentQuestion;
3306	mDNSBool followcname = FollowCNAME(q, &rr->resrec, AddRecord);
3307
3308	verbosedebugf("AnswerCurrentQuestionWithResourceRecord:%4lu %s TTL %d %s",
3309		q->CurrentAnswers, AddRecord ? "Add" : "Rmv", rr->resrec.rroriginalttl, CRDisplayString(m, rr));
3310
3311	// Normally we don't send out the unicast query if we have answered using our local only auth records e.g., /etc/hosts.
3312	// But if the query for "A" record has a local answer but query for "AAAA" record has no local answer, we might
3313	// send the AAAA query out which will come back with CNAME and will also answer the "A" query. To prevent that,
3314	// we check to see if that query already has a unique local answer.
3315	if (q->LOAddressAnswers)
3316		{
3317		LogInfo("AnswerCurrentQuestionWithResourceRecord: Question %p %##s (%s) not answering with record %s due to "
3318			"LOAddressAnswers %d", q, q->qname.c, DNSTypeName(q->qtype), ARDisplayString(m, rr),
3319			q->LOAddressAnswers);
3320		return;
3321		}
3322
3323	if (QuerySuppressed(q))
3324		{
3325		// If the query is suppressed, then we don't want to answer from the cache. But if this query is
3326		// supposed to time out, we still want to callback the clients. We do this only for TimeoutQuestions
3327		// that are timing out, which we know are answered with Negative cache record when timing out.
3328		if (!q->TimeoutQuestion || rr->resrec.RecordType != kDNSRecordTypePacketNegative || (m->timenow - q->StopTime < 0))
3329			return;
3330		}
3331
3332	// Note: Use caution here. In the case of records with rr->DelayDelivery set, AnswerCurrentQuestionWithResourceRecord(... mDNStrue)
3333	// may be called twice, once when the record is received, and again when it's time to notify local clients.
3334	// If any counters or similar are added here, care must be taken to ensure that they are not double-incremented by this.
3335
3336	rr->LastUsed = m->timenow;
3337	if (AddRecord == QC_add && !q->DuplicateOf && rr->CRActiveQuestion != q)
3338		{
3339		if (!rr->CRActiveQuestion) m->rrcache_active++;	// If not previously active, increment rrcache_active count
3340		debugf("AnswerCurrentQuestionWithResourceRecord: Updating CRActiveQuestion from %p to %p for cache record %s, CurrentAnswer %d",
3341			rr->CRActiveQuestion, q, CRDisplayString(m,rr), q->CurrentAnswers);
3342		rr->CRActiveQuestion = q;						// We know q is non-null
3343		SetNextCacheCheckTimeForRecord(m, rr);
3344		}
3345
3346	// If this is:
3347	// (a) a no-cache add, where we've already done at least one 'QM' query, or
3348	// (b) a normal add, where we have at least one unique-type answer,
3349	// then there's no need to keep polling the network.
3350	// (If we have an answer in the cache, then we'll automatically ask again in time to stop it expiring.)
3351	// We do this for mDNS questions and uDNS one-shot questions, but not for
3352	// uDNS LongLived questions, because that would mess up our LLQ lease renewal timing.
3353	if ((AddRecord == QC_addnocache && !q->RequestUnicast) ||
3354		(AddRecord == QC_add && (q->ExpectUnique || (rr->resrec.RecordType & kDNSRecordTypePacketUniqueMask))))
3355		if (ActiveQuestion(q) && (mDNSOpaque16IsZero(q->TargetQID) || !q->LongLived))
3356			{
3357			q->LastQTime        = m->timenow;
3358			q->LastQTxTime      = m->timenow;
3359			q->RecentAnswerPkts = 0;
3360			q->ThisQInterval    = MaxQuestionInterval;
3361			q->RequestUnicast   = mDNSfalse;
3362			debugf("AnswerCurrentQuestionWithResourceRecord: Set MaxQuestionInterval for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
3363			}
3364
3365	if (rr->DelayDelivery) return;		// We'll come back later when CacheRecordDeferredAdd() calls us
3366
3367	// Only deliver negative answers if client has explicitly requested them
3368	if (rr->resrec.RecordType == kDNSRecordTypePacketNegative || (q->qtype != kDNSType_NSEC && RRAssertsNonexistence(&rr->resrec, q->qtype)))
3369		if (!AddRecord || !q->ReturnIntermed) return;
3370
3371	// For CNAME results to non-CNAME questions, only inform the client if they explicitly requested that
3372	if (q->QuestionCallback && !q->NoAnswer && (!followcname || q->ReturnIntermed))
3373		{
3374		mDNS_DropLockBeforeCallback();		// Allow client (and us) to legally make mDNS API calls
3375		if (q->qtype != kDNSType_NSEC && RRAssertsNonexistence(&rr->resrec, q->qtype))
3376			{
3377			CacheRecord neg;
3378			MakeNegativeCacheRecord(m, &neg, &q->qname, q->qnamehash, q->qtype, q->qclass, 1, rr->resrec.InterfaceID, q->qDNSServer);
3379			q->QuestionCallback(m, q, &neg.resrec, AddRecord);
3380			}
3381		else
3382			q->QuestionCallback(m, q, &rr->resrec, AddRecord);
3383		mDNS_ReclaimLockAfterCallback();	// Decrement mDNS_reentrancy to block mDNS API calls again
3384		}
3385	// Note: Proceed with caution here because client callback function is allowed to do anything,
3386	// including starting/stopping queries, registering/deregistering records, etc.
3387
3388	if (followcname && m->CurrentQuestion == q)
3389		AnswerQuestionByFollowingCNAME(m, q, &rr->resrec);
3390	}
3391
3392// New Questions are answered through AnswerNewQuestion. But there may not have been any
3393// matching cache records for the questions when it is called. There are two possibilities.
3394//
3395// 1) There are no cache records
3396// 2) There are cache records but the DNSServers between question and cache record don't match.
3397//
3398// In the case of (1), where there are no cache records and later we add them when we get a response,
3399// CacheRecordAdd/CacheRecordDeferredAdd will take care of adding the cache and delivering the ADD
3400// events to the application. If we already have a cache entry, then no ADD events are delivered
3401// unless the RDATA has changed
3402//
3403// In the case of (2) where we had the cache records and did not answer because of the DNSServer mismatch,
3404// we need to answer them whenever we change the DNSServer.  But we can't do it at the instant the DNSServer
3405// changes because when we do the callback, the question can get deleted and the calling function would not
3406// know how to handle it. So, we run this function from mDNS_Execute to handle DNSServer changes on the
3407// question
3408
3409mDNSlocal void AnswerQuestionsForDNSServerChanges(mDNS *const m)
3410	{
3411	DNSQuestion *q;
3412	DNSQuestion *qnext;
3413	CacheRecord *rr;
3414	mDNSu32 slot;
3415	CacheGroup *cg;
3416
3417	if (m->CurrentQuestion)
3418		LogMsg("AnswerQuestionsForDNSServerChanges: ERROR m->CurrentQuestion already set: %##s (%s)",
3419				m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
3420
3421	for (q = m->Questions; q && q != m->NewQuestions; q = qnext)
3422		{
3423		qnext = q->next;
3424
3425		// multicast or DNSServers did not change.
3426		if (mDNSOpaque16IsZero(q->TargetQID)) continue;
3427		if (!q->deliverAddEvents) continue;
3428
3429		// We are going to look through the cache for this question since it changed
3430		// its DNSserver last time. Reset it so that we don't call them again. Calling
3431		// them again will deliver duplicate events to the application
3432		q->deliverAddEvents = mDNSfalse;
3433		if (QuerySuppressed(q)) continue;
3434		m->CurrentQuestion = q;
3435		slot = HashSlot(&q->qname);
3436		cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
3437		for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
3438			{
3439			if (SameNameRecordAnswersQuestion(&rr->resrec, q))
3440				{
3441				LogInfo("AnswerQuestionsForDNSServerChanges: Calling AnswerCurrentQuestionWithResourceRecord for question %p %##s using resource record %s",
3442					q, q->qname.c, CRDisplayString(m, rr));
3443				// When this question penalizes a DNS server and has no more DNS servers to pick, we normally
3444				// deliver a negative cache response and suspend the question for 60 seconds (see uDNS_CheckCurrentQuestion).
3445				// But sometimes we may already find the negative cache entry and deliver that here as the process
3446				// of changing DNS servers. When the cache entry is about to expire, we will resend the question and
3447				// that time, we need to make sure that we have a valid DNS server. Otherwise, we will deliver
3448				// a negative cache response without trying the server.
3449				if (!q->qDNSServer && !q->DuplicateOf && rr->resrec.RecordType == kDNSRecordTypePacketNegative)
3450					{
3451					DNSQuestion *qptr;
3452					SetValidDNSServers(m, q);
3453					q->qDNSServer = GetServerForQuestion(m, q);
3454					for (qptr = q->next ; qptr; qptr = qptr->next)
3455						if (qptr->DuplicateOf == q) { qptr->validDNSServers = q->validDNSServers; qptr->qDNSServer = q->qDNSServer; }
3456					}
3457				q->CurrentAnswers++;
3458				if (rr->resrec.rdlength > SmallRecordLimit) q->LargeAnswers++;
3459				if (rr->resrec.RecordType & kDNSRecordTypePacketUniqueMask) q->UniqueAnswers++;
3460				AnswerCurrentQuestionWithResourceRecord(m, rr, QC_add);
3461				if (m->CurrentQuestion != q) break;		// If callback deleted q, then we're finished here
3462				}
3463			}
3464		}
3465		m->CurrentQuestion = mDNSNULL;
3466	}
3467
3468mDNSlocal void CacheRecordDeferredAdd(mDNS *const m, CacheRecord *rr)
3469	{
3470	rr->DelayDelivery = 0;
3471	if (m->CurrentQuestion)
3472		LogMsg("CacheRecordDeferredAdd ERROR m->CurrentQuestion already set: %##s (%s)",
3473			m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
3474	m->CurrentQuestion = m->Questions;
3475	while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
3476		{
3477		DNSQuestion *q = m->CurrentQuestion;
3478		if (ResourceRecordAnswersQuestion(&rr->resrec, q))
3479			AnswerCurrentQuestionWithResourceRecord(m, rr, QC_add);
3480		if (m->CurrentQuestion == q)	// If m->CurrentQuestion was not auto-advanced, do it ourselves now
3481			m->CurrentQuestion = q->next;
3482		}
3483	m->CurrentQuestion = mDNSNULL;
3484	}
3485
3486mDNSlocal mDNSs32 CheckForSoonToExpireRecords(mDNS *const m, const domainname *const name, const mDNSu32 namehash, const mDNSu32 slot)
3487	{
3488	const mDNSs32 threshhold = m->timenow + mDNSPlatformOneSecond;	// See if there are any records expiring within one second
3489	const mDNSs32 start      = m->timenow - 0x10000000;
3490	mDNSs32 delay = start;
3491	CacheGroup *cg = CacheGroupForName(m, slot, namehash, name);
3492	const CacheRecord *rr;
3493	for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
3494		if (threshhold - RRExpireTime(rr) >= 0)		// If we have records about to expire within a second
3495			if (delay - RRExpireTime(rr) < 0)		// then delay until after they've been deleted
3496				delay = RRExpireTime(rr);
3497	if (delay - start > 0) return(NonZeroTime(delay));
3498	else return(0);
3499	}
3500
3501// CacheRecordAdd is only called from CreateNewCacheEntry, *never* directly as a result of a client API call.
3502// If new questions are created as a result of invoking client callbacks, they will be added to
3503// the end of the question list, and m->NewQuestions will be set to indicate the first new question.
3504// rr is a new CacheRecord just received into our cache
3505// (kDNSRecordTypePacketAns/PacketAnsUnique/PacketAdd/PacketAddUnique).
3506// Note: CacheRecordAdd calls AnswerCurrentQuestionWithResourceRecord which can call a user callback,
3507// which may change the record list and/or question list.
3508// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
3509mDNSlocal void CacheRecordAdd(mDNS *const m, CacheRecord *rr)
3510	{
3511	DNSQuestion *q;
3512
3513	// We stop when we get to NewQuestions -- if we increment their CurrentAnswers/LargeAnswers/UniqueAnswers
3514	// counters here we'll end up double-incrementing them when we do it again in AnswerNewQuestion().
3515	for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
3516		{
3517		if (ResourceRecordAnswersQuestion(&rr->resrec, q))
3518			{
3519			// If this question is one that's actively sending queries, and it's received ten answers within one
3520			// second of sending the last query packet, then that indicates some radical network topology change,
3521			// so reset its exponential backoff back to the start. We must be at least at the eight-second interval
3522			// to do this. If we're at the four-second interval, or less, there's not much benefit accelerating
3523			// because we will anyway send another query within a few seconds. The first reset query is sent out
3524			// randomized over the next four seconds to reduce possible synchronization between machines.
3525			if (q->LastAnswerPktNum != m->PktNum)
3526				{
3527				q->LastAnswerPktNum = m->PktNum;
3528				if (mDNSOpaque16IsZero(q->TargetQID) && ActiveQuestion(q) && ++q->RecentAnswerPkts >= 10 &&
3529					q->ThisQInterval > InitialQuestionInterval * QuestionIntervalStep3 && m->timenow - q->LastQTxTime < mDNSPlatformOneSecond)
3530					{
3531					LogMsg("CacheRecordAdd: %##s (%s) got immediate answer burst (%d); restarting exponential backoff sequence (%d)",
3532						q->qname.c, DNSTypeName(q->qtype), q->RecentAnswerPkts, q->ThisQInterval);
3533					q->LastQTime      = m->timenow - InitialQuestionInterval + (mDNSs32)mDNSRandom((mDNSu32)mDNSPlatformOneSecond*4);
3534					q->ThisQInterval  = InitialQuestionInterval;
3535					SetNextQueryTime(m,q);
3536					}
3537				}
3538			verbosedebugf("CacheRecordAdd %p %##s (%s) %lu %#a:%d question %p", rr, rr->resrec.name->c,
3539				DNSTypeName(rr->resrec.rrtype), rr->resrec.rroriginalttl, rr->resrec.rDNSServer ?
3540				&rr->resrec.rDNSServer->addr : mDNSNULL, mDNSVal16(rr->resrec.rDNSServer ?
3541				rr->resrec.rDNSServer->port : zeroIPPort), q);
3542			q->CurrentAnswers++;
3543			q->unansweredQueries = 0;
3544			if (rr->resrec.rdlength > SmallRecordLimit) q->LargeAnswers++;
3545			if (rr->resrec.RecordType & kDNSRecordTypePacketUniqueMask) q->UniqueAnswers++;
3546			if (q->CurrentAnswers > 4000)
3547				{
3548				static int msgcount = 0;
3549				if (msgcount++ < 10)
3550					LogMsg("CacheRecordAdd: %##s (%s) has %d answers; shedding records to resist DOS attack",
3551						q->qname.c, DNSTypeName(q->qtype), q->CurrentAnswers);
3552				rr->resrec.rroriginalttl = 0;
3553				rr->UnansweredQueries = MaxUnansweredQueries;
3554				}
3555			}
3556		}
3557
3558	if (!rr->DelayDelivery)
3559		{
3560		if (m->CurrentQuestion)
3561			LogMsg("CacheRecordAdd ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
3562		m->CurrentQuestion = m->Questions;
3563		while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
3564			{
3565			q = m->CurrentQuestion;
3566			if (ResourceRecordAnswersQuestion(&rr->resrec, q))
3567				AnswerCurrentQuestionWithResourceRecord(m, rr, QC_add);
3568			if (m->CurrentQuestion == q)	// If m->CurrentQuestion was not auto-advanced, do it ourselves now
3569				m->CurrentQuestion = q->next;
3570			}
3571		m->CurrentQuestion = mDNSNULL;
3572		}
3573
3574	SetNextCacheCheckTimeForRecord(m, rr);
3575	}
3576
3577// NoCacheAnswer is only called from mDNSCoreReceiveResponse, *never* directly as a result of a client API call.
3578// If new questions are created as a result of invoking client callbacks, they will be added to
3579// the end of the question list, and m->NewQuestions will be set to indicate the first new question.
3580// rr is a new CacheRecord just received from the wire (kDNSRecordTypePacketAns/AnsUnique/Add/AddUnique)
3581// but we don't have any place to cache it. We'll deliver question 'add' events now, but we won't have any
3582// way to deliver 'remove' events in future, nor will we be able to include this in known-answer lists,
3583// so we immediately bump ThisQInterval up to MaxQuestionInterval to avoid pounding the network.
3584// Note: NoCacheAnswer calls AnswerCurrentQuestionWithResourceRecord which can call a user callback,
3585// which may change the record list and/or question list.
3586// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
3587mDNSlocal void NoCacheAnswer(mDNS *const m, CacheRecord *rr)
3588	{
3589	LogMsg("No cache space: Delivering non-cached result for %##s", m->rec.r.resrec.name->c);
3590	if (m->CurrentQuestion)
3591		LogMsg("NoCacheAnswer ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
3592	m->CurrentQuestion = m->Questions;
3593	// We do this for *all* questions, not stopping when we get to m->NewQuestions,
3594	// since we're not caching the record and we'll get no opportunity to do this later
3595	while (m->CurrentQuestion)
3596		{
3597		DNSQuestion *q = m->CurrentQuestion;
3598		if (ResourceRecordAnswersQuestion(&rr->resrec, q))
3599			AnswerCurrentQuestionWithResourceRecord(m, rr, QC_addnocache);	// QC_addnocache means "don't expect remove events for this"
3600		if (m->CurrentQuestion == q)	// If m->CurrentQuestion was not auto-advanced, do it ourselves now
3601			m->CurrentQuestion = q->next;
3602		}
3603	m->CurrentQuestion = mDNSNULL;
3604	}
3605
3606// CacheRecordRmv is only called from CheckCacheExpiration, which is called from mDNS_Execute.
3607// Note that CacheRecordRmv is *only* called for records that are referenced by at least one active question.
3608// If new questions are created as a result of invoking client callbacks, they will be added to
3609// the end of the question list, and m->NewQuestions will be set to indicate the first new question.
3610// rr is an existing cache CacheRecord that just expired and is being deleted
3611// (kDNSRecordTypePacketAns/PacketAnsUnique/PacketAdd/PacketAddUnique).
3612// Note: CacheRecordRmv calls AnswerCurrentQuestionWithResourceRecord which can call a user callback,
3613// which may change the record list and/or question list.
3614// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
3615mDNSlocal void CacheRecordRmv(mDNS *const m, CacheRecord *rr)
3616	{
3617	if (m->CurrentQuestion)
3618		LogMsg("CacheRecordRmv ERROR m->CurrentQuestion already set: %##s (%s)",
3619			m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
3620	m->CurrentQuestion = m->Questions;
3621
3622	// We stop when we get to NewQuestions -- for new questions their CurrentAnswers/LargeAnswers/UniqueAnswers counters
3623	// will all still be zero because we haven't yet gone through the cache counting how many answers we have for them.
3624	while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
3625		{
3626		DNSQuestion *q = m->CurrentQuestion;
3627		// When a question enters suppressed state, we generate RMV events and generate a negative
3628		// response. A cache may be present that answers this question e.g., cache entry generated
3629		// before the question became suppressed. We need to skip the suppressed questions here as
3630		// the RMV event has already been generated.
3631		if (!QuerySuppressed(q) && ResourceRecordAnswersQuestion(&rr->resrec, q))
3632			{
3633			verbosedebugf("CacheRecordRmv %p %s", rr, CRDisplayString(m, rr));
3634			q->FlappingInterface1 = mDNSNULL;
3635			q->FlappingInterface2 = mDNSNULL;
3636
3637			// When a question changes DNS server, it is marked with deliverAddEvents if we find any
3638			// cache entry corresponding to the new DNS server. Before we deliver the ADD event, the
3639			// cache entry may be removed in which case CurrentAnswers can be zero.
3640			if (q->deliverAddEvents && !q->CurrentAnswers)
3641				{
3642				LogInfo("CacheRecordRmv: Question %p %##s (%s) deliverAddEvents set, DNSServer %#a:%d",
3643					q, q->qname.c, DNSTypeName(q->qtype), q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL,
3644					mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zeroIPPort));
3645				m->CurrentQuestion = q->next;
3646				continue;
3647				}
3648			if (q->CurrentAnswers == 0)
3649				LogMsg("CacheRecordRmv ERROR!!: How can CurrentAnswers already be zero for %p %##s (%s) DNSServer %#a:%d",
3650					q, q->qname.c, DNSTypeName(q->qtype), q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL,
3651					mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zeroIPPort));
3652			else
3653				{
3654				q->CurrentAnswers--;
3655				if (rr->resrec.rdlength > SmallRecordLimit) q->LargeAnswers--;
3656				if (rr->resrec.RecordType & kDNSRecordTypePacketUniqueMask) q->UniqueAnswers--;
3657				}
3658			if (rr->resrec.rdata->MaxRDLength) // Never generate "remove" events for negative results
3659				{
3660				if (q->CurrentAnswers == 0)
3661					{
3662					LogInfo("CacheRecordRmv: Last answer for %##s (%s) expired from cache; will reconfirm antecedents",
3663						q->qname.c, DNSTypeName(q->qtype));
3664					ReconfirmAntecedents(m, &q->qname, q->qnamehash, 0);
3665					}
3666				AnswerCurrentQuestionWithResourceRecord(m, rr, QC_rmv);
3667				}
3668			}
3669		if (m->CurrentQuestion == q)	// If m->CurrentQuestion was not auto-advanced, do it ourselves now
3670			m->CurrentQuestion = q->next;
3671		}
3672	m->CurrentQuestion = mDNSNULL;
3673	}
3674
3675mDNSlocal void ReleaseCacheEntity(mDNS *const m, CacheEntity *e)
3676	{
3677#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
3678	unsigned int i;
3679	for (i=0; i<sizeof(*e); i++) ((char*)e)[i] = 0xFF;
3680#endif
3681	e->next = m->rrcache_free;
3682	m->rrcache_free = e;
3683	m->rrcache_totalused--;
3684	}
3685
3686mDNSlocal void ReleaseCacheGroup(mDNS *const m, CacheGroup **cp)
3687	{
3688	CacheEntity *e = (CacheEntity *)(*cp);
3689	//LogMsg("ReleaseCacheGroup:  Releasing CacheGroup for %p, %##s", (*cp)->name->c, (*cp)->name->c);
3690	if ((*cp)->rrcache_tail != &(*cp)->members)
3691		LogMsg("ERROR: (*cp)->members == mDNSNULL but (*cp)->rrcache_tail != &(*cp)->members)");
3692	//if ((*cp)->name != (domainname*)((*cp)->namestorage))
3693	//	LogMsg("ReleaseCacheGroup: %##s, %p %p", (*cp)->name->c, (*cp)->name, (domainname*)((*cp)->namestorage));
3694	if ((*cp)->name != (domainname*)((*cp)->namestorage)) mDNSPlatformMemFree((*cp)->name);
3695	(*cp)->name = mDNSNULL;
3696	*cp = (*cp)->next;			// Cut record from list
3697	ReleaseCacheEntity(m, e);
3698	}
3699
3700mDNSlocal void ReleaseCacheRecord(mDNS *const m, CacheRecord *r)
3701	{
3702	//LogMsg("ReleaseCacheRecord: Releasing %s", CRDisplayString(m, r));
3703	if (r->resrec.rdata && r->resrec.rdata != (RData*)&r->smallrdatastorage) mDNSPlatformMemFree(r->resrec.rdata);
3704	r->resrec.rdata = mDNSNULL;
3705	ReleaseCacheEntity(m, (CacheEntity *)r);
3706	}
3707
3708// Note: We want to be careful that we deliver all the CacheRecordRmv calls before delivering
3709// CacheRecordDeferredAdd calls. The in-order nature of the cache lists ensures that all
3710// callbacks for old records are delivered before callbacks for newer records.
3711mDNSlocal void CheckCacheExpiration(mDNS *const m, const mDNSu32 slot, CacheGroup *const cg)
3712	{
3713	CacheRecord **rp = &cg->members;
3714
3715	if (m->lock_rrcache) { LogMsg("CheckCacheExpiration ERROR! Cache already locked!"); return; }
3716	m->lock_rrcache = 1;
3717
3718	while (*rp)
3719		{
3720		CacheRecord *const rr = *rp;
3721		mDNSs32 event = RRExpireTime(rr);
3722		if (m->timenow - event >= 0)	// If expired, delete it
3723			{
3724			*rp = rr->next;				// Cut it from the list
3725			verbosedebugf("CheckCacheExpiration: Deleting%7d %7d %p %s",
3726				m->timenow - rr->TimeRcvd, rr->resrec.rroriginalttl, rr->CRActiveQuestion, CRDisplayString(m, rr));
3727			if (rr->CRActiveQuestion)	// If this record has one or more active questions, tell them it's going away
3728				{
3729				DNSQuestion *q = rr->CRActiveQuestion;
3730				// When a cache record is about to expire, we expect to do four queries at 80-82%, 85-87%, 90-92% and
3731				// then 95-97% of the TTL. If the DNS server does not respond, then we will remove the cache entry
3732				// before we pick a new DNS server. As the question interval is set to MaxQuestionInterval, we may
3733				// not send out a query anytime soon. Hence, we need to reset the question interval. If this is
3734				// a normal deferred ADD case, then AnswerCurrentQuestionWithResourceRecord will reset it to
3735				// MaxQuestionInterval. If we have inactive questions referring to negative cache entries,
3736				// don't ressurect them as they will deliver duplicate "No such Record" ADD events
3737				if (!mDNSOpaque16IsZero(q->TargetQID) && !q->LongLived && ActiveQuestion(q))
3738					{
3739					q->ThisQInterval = InitialQuestionInterval;
3740					q->LastQTime     = m->timenow - q->ThisQInterval;
3741					SetNextQueryTime(m, q);
3742					}
3743				CacheRecordRmv(m, rr);
3744				m->rrcache_active--;
3745				}
3746			ReleaseCacheRecord(m, rr);
3747			}
3748		else							// else, not expired; see if we need to query
3749			{
3750			// If waiting to delay delivery, do nothing until then
3751			if (rr->DelayDelivery && rr->DelayDelivery - m->timenow > 0)
3752				event = rr->DelayDelivery;
3753			else
3754				{
3755				if (rr->DelayDelivery) CacheRecordDeferredAdd(m, rr);
3756				if (rr->CRActiveQuestion && rr->UnansweredQueries < MaxUnansweredQueries)
3757					{
3758					if (m->timenow - rr->NextRequiredQuery < 0)		// If not yet time for next query
3759						event = NextCacheCheckEvent(rr);			// then just record when we want the next query
3760					else											// else trigger our question to go out now
3761						{
3762						// Set NextScheduledQuery to timenow so that SendQueries() will run.
3763						// SendQueries() will see that we have records close to expiration, and send FEQs for them.
3764						m->NextScheduledQuery = m->timenow;
3765						// After sending the query we'll increment UnansweredQueries and call SetNextCacheCheckTimeForRecord(),
3766						// which will correctly update m->NextCacheCheck for us.
3767						event = m->timenow + 0x3FFFFFFF;
3768						}
3769					}
3770				}
3771			verbosedebugf("CheckCacheExpiration:%6d %5d %s",
3772				(event - m->timenow) / mDNSPlatformOneSecond, CacheCheckGracePeriod(rr), CRDisplayString(m, rr));
3773			if (m->rrcache_nextcheck[slot] - event > 0)
3774				m->rrcache_nextcheck[slot] = event;
3775			rp = &rr->next;
3776			}
3777		}
3778	if (cg->rrcache_tail != rp) verbosedebugf("CheckCacheExpiration: Updating CacheGroup tail from %p to %p", cg->rrcache_tail, rp);
3779	cg->rrcache_tail = rp;
3780	m->lock_rrcache = 0;
3781	}
3782
3783mDNSlocal void AnswerNewQuestion(mDNS *const m)
3784	{
3785	mDNSBool ShouldQueryImmediately = mDNStrue;
3786	DNSQuestion *const q = m->NewQuestions;		// Grab the question we're going to answer
3787	mDNSu32 slot = HashSlot(&q->qname);
3788	CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
3789	AuthRecord *lr;
3790	AuthGroup *ag;
3791	mDNSBool AnsweredFromCache = mDNSfalse;
3792
3793	verbosedebugf("AnswerNewQuestion: Answering %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
3794
3795	if (cg) CheckCacheExpiration(m, slot, cg);
3796	if (m->NewQuestions != q) { LogInfo("AnswerNewQuestion: Question deleted while doing CheckCacheExpiration"); goto exit; }
3797	m->NewQuestions = q->next;
3798	// Advance NewQuestions to the next *after* calling CheckCacheExpiration, because if we advance it first
3799	// then CheckCacheExpiration may give this question add/remove callbacks, and it's not yet ready for that.
3800	//
3801	// Also, CheckCacheExpiration() calls CacheRecordDeferredAdd() and CacheRecordRmv(), which invoke
3802	// client callbacks, which may delete their own or any other question. Our mechanism for detecting
3803	// whether our current m->NewQuestions question got deleted by one of these callbacks is to store the
3804	// value of m->NewQuestions in 'q' before calling CheckCacheExpiration(), and then verify afterwards
3805	// that they're still the same. If m->NewQuestions has changed (because mDNS_StopQuery_internal
3806	// advanced it), that means the question was deleted, so we no longer need to worry about answering
3807	// it (and indeed 'q' is now a dangling pointer, so dereferencing it at all would be bad, and the
3808	// values we computed for slot and cg are now stale and relate to a question that no longer exists).
3809	//
3810	// We can't use the usual m->CurrentQuestion mechanism for this because  CacheRecordDeferredAdd() and
3811	// CacheRecordRmv() both use that themselves when walking the list of (non-new) questions generating callbacks.
3812	// Fortunately mDNS_StopQuery_internal auto-advances both m->CurrentQuestion *AND* m->NewQuestions when
3813	// deleting a question, so luckily we have an easy alternative way of detecting if our question got deleted.
3814
3815	if (m->lock_rrcache) LogMsg("AnswerNewQuestion ERROR! Cache already locked!");
3816	// This should be safe, because calling the client's question callback may cause the
3817	// question list to be modified, but should not ever cause the rrcache list to be modified.
3818	// If the client's question callback deletes the question, then m->CurrentQuestion will
3819	// be advanced, and we'll exit out of the loop
3820	m->lock_rrcache = 1;
3821	if (m->CurrentQuestion)
3822		LogMsg("AnswerNewQuestion ERROR m->CurrentQuestion already set: %##s (%s)",
3823			m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
3824	m->CurrentQuestion = q;		// Indicate which question we're answering, so we'll know if it gets deleted
3825
3826	if (q->NoAnswer == NoAnswer_Fail)
3827		{
3828		LogMsg("AnswerNewQuestion: NoAnswer_Fail %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
3829		MakeNegativeCacheRecord(m, &m->rec.r, &q->qname, q->qnamehash, q->qtype, q->qclass, 60, mDNSInterface_Any, q->qDNSServer);
3830		q->NoAnswer = NoAnswer_Normal;		// Temporarily turn off answer suppression
3831		AnswerCurrentQuestionWithResourceRecord(m, &m->rec.r, QC_addnocache);
3832		// Don't touch the question if it has been stopped already
3833		if (m->CurrentQuestion == q) q->NoAnswer = NoAnswer_Fail;		// Restore NoAnswer state
3834		m->rec.r.resrec.RecordType = 0;		// Clear RecordType to show we're not still using it
3835		}
3836	if (m->CurrentQuestion != q) { LogInfo("AnswerNewQuestion: Question deleted while generating NoAnswer_Fail response"); goto exit; }
3837
3838	// See if we want to tell it about LocalOnly records
3839	if (m->CurrentRecord)
3840		LogMsg("AnswerNewQuestion ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
3841	slot = AuthHashSlot(&q->qname);
3842	ag = AuthGroupForName(&m->rrauth, slot, q->qnamehash, &q->qname);
3843	if (ag)
3844		{
3845		m->CurrentRecord = ag->members;
3846		while (m->CurrentRecord && m->CurrentRecord != ag->NewLocalOnlyRecords)
3847			{
3848			AuthRecord *rr = m->CurrentRecord;
3849			m->CurrentRecord = rr->next;
3850			//
3851			// If the question is mDNSInterface_LocalOnly, all records local to the machine should be used
3852			// to answer the query. This is handled in AnswerNewLocalOnlyQuestion.
3853			//
3854			// We handle mDNSInterface_Any and scoped questions here. See LocalOnlyRecordAnswersQuestion for more
3855			// details on how we handle this case. For P2P we just handle "Interface_Any" questions. For LocalOnly
3856			// we handle both mDNSInterface_Any and scoped questions.
3857
3858			if (rr->ARType == AuthRecordLocalOnly || (rr->ARType == AuthRecordP2P && q->InterfaceID == mDNSInterface_Any))
3859				if (LocalOnlyRecordAnswersQuestion(rr, q))
3860					{
3861					AnswerLocalQuestionWithLocalAuthRecord(m, rr, mDNStrue);
3862					if (m->CurrentQuestion != q) break;		// If callback deleted q, then we're finished here
3863					}
3864			}
3865		}
3866	m->CurrentRecord = mDNSNULL;
3867
3868	if (m->CurrentQuestion != q) { LogInfo("AnswerNewQuestion: Question deleted while while giving LocalOnly record answers"); goto exit; }
3869
3870	if (q->LOAddressAnswers)
3871		{
3872		LogInfo("AnswerNewQuestion: Question %p %##s (%s) answered using local auth records LOAddressAnswers %d",
3873			q, q->qname.c, DNSTypeName(q->qtype), q->LOAddressAnswers);
3874		goto exit;
3875		}
3876
3877	// Before we go check the cache and ship this query on the wire, we have to be sure that there are
3878	// no local records that could possibly answer this question. As we did not check the NewLocalRecords, we
3879	// need to just peek at them to see whether it will answer this question. If it would answer, pretend
3880	// that we answered. AnswerAllLocalQuestionsWithLocalAuthRecord will answer shortly. This happens normally
3881	// when we add new /etc/hosts entries and restart the question. It is a new question and also a new record.
3882	if (ag)
3883		{
3884		lr = ag->NewLocalOnlyRecords;
3885		while (lr)
3886			{
3887			if (LORecordAnswersAddressType(lr) && LocalOnlyRecordAnswersQuestion(lr, q))
3888				{
3889				LogInfo("AnswerNewQuestion: Question %p %##s (%s) will be answered using new local auth records "
3890					" LOAddressAnswers %d", q, q->qname.c, DNSTypeName(q->qtype), q->LOAddressAnswers);
3891				goto exit;
3892				}
3893			lr = lr->next;
3894			}
3895		}
3896
3897
3898	// If we are not supposed to answer this question, generate a negative response.
3899	// Temporarily suspend the SuppressQuery so that AnswerCurrentQuestionWithResourceRecord can answer the question
3900	if (QuerySuppressed(q)) { q->SuppressQuery = mDNSfalse; GenerateNegativeResponse(m); q->SuppressQuery = mDNStrue; }
3901	else
3902		{
3903		CacheRecord *rr;
3904		for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
3905			if (SameNameRecordAnswersQuestion(&rr->resrec, q))
3906				{
3907				// SecsSinceRcvd is whole number of elapsed seconds, rounded down
3908				mDNSu32 SecsSinceRcvd = ((mDNSu32)(m->timenow - rr->TimeRcvd)) / mDNSPlatformOneSecond;
3909				if (rr->resrec.rroriginalttl <= SecsSinceRcvd)
3910					{
3911					LogMsg("AnswerNewQuestion: How is rr->resrec.rroriginalttl %lu <= SecsSinceRcvd %lu for %s %d %d",
3912						rr->resrec.rroriginalttl, SecsSinceRcvd, CRDisplayString(m, rr), m->timenow, rr->TimeRcvd);
3913					continue;	// Go to next one in loop
3914					}
3915
3916				// If this record set is marked unique, then that means we can reasonably assume we have the whole set
3917				// -- we don't need to rush out on the network and query immediately to see if there are more answers out there
3918				if ((rr->resrec.RecordType & kDNSRecordTypePacketUniqueMask) || (q->ExpectUnique))
3919					ShouldQueryImmediately = mDNSfalse;
3920				q->CurrentAnswers++;
3921				if (rr->resrec.rdlength > SmallRecordLimit) q->LargeAnswers++;
3922				if (rr->resrec.RecordType & kDNSRecordTypePacketUniqueMask) q->UniqueAnswers++;
3923				AnsweredFromCache = mDNStrue;
3924				AnswerCurrentQuestionWithResourceRecord(m, rr, QC_add);
3925				if (m->CurrentQuestion != q) break;		// If callback deleted q, then we're finished here
3926				}
3927			else if (RRTypeIsAddressType(rr->resrec.rrtype) && RRTypeIsAddressType(q->qtype))
3928				ShouldQueryImmediately = mDNSfalse;
3929		}
3930	// We don't use LogInfo for this "Question deleted" message because it happens so routinely that
3931	// it's not remotely remarkable, and therefore unlikely to be of much help tracking down bugs.
3932	if (m->CurrentQuestion != q) { debugf("AnswerNewQuestion: Question deleted while giving cache answers"); goto exit; }
3933
3934	// Neither a local record nor a cache entry could answer this question. If this question need to be retried
3935	// with search domains, generate a negative response which will now retry after appending search domains.
3936	// If the query was suppressed above, we already generated a negative response. When it gets unsuppressed,
3937	// we will retry with search domains.
3938	if (!QuerySuppressed(q) && !AnsweredFromCache && q->RetryWithSearchDomains)
3939		{
3940		LogInfo("AnswerNewQuestion: Generating response for retrying with search domains %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
3941		GenerateNegativeResponse(m);
3942		}
3943
3944	if (m->CurrentQuestion != q) { debugf("AnswerNewQuestion: Question deleted while giving negative answer"); goto exit; }
3945
3946	// Note: When a query gets suppressed or retried with search domains, we de-activate the question.
3947	// Hence we don't execute the following block of code for those cases.
3948	if (ShouldQueryImmediately && ActiveQuestion(q))
3949		{
3950		debugf("AnswerNewQuestion: ShouldQueryImmediately %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
3951		q->ThisQInterval  = InitialQuestionInterval;
3952		q->LastQTime      = m->timenow - q->ThisQInterval;
3953		if (mDNSOpaque16IsZero(q->TargetQID))		// For mDNS, spread packets to avoid a burst of simultaneous queries
3954			{
3955			// Compute random delay in the range 1-6 seconds, then divide by 50 to get 20-120ms
3956			if (!m->RandomQueryDelay)
3957				m->RandomQueryDelay = (mDNSPlatformOneSecond + mDNSRandom(mDNSPlatformOneSecond*5) - 1) / 50 + 1;
3958			q->LastQTime += m->RandomQueryDelay;
3959			}
3960		}
3961
3962	// IN ALL CASES make sure that m->NextScheduledQuery is set appropriately.
3963	// In cases where m->NewQuestions->DelayAnswering is set, we may have delayed generating our
3964	// answers for this question until *after* its scheduled transmission time, in which case
3965	// m->NextScheduledQuery may now be set to 'never', and in that case -- even though we're *not* doing
3966	// ShouldQueryImmediately -- we still need to make sure we set m->NextScheduledQuery correctly.
3967	SetNextQueryTime(m,q);
3968
3969exit:
3970	m->CurrentQuestion = mDNSNULL;
3971	m->lock_rrcache = 0;
3972	}
3973
3974// When a NewLocalOnlyQuestion is created, AnswerNewLocalOnlyQuestion runs though our ResourceRecords delivering any
3975// appropriate answers, stopping if it reaches a NewLocalOnlyRecord -- these will be handled by AnswerAllLocalQuestionsWithLocalAuthRecord
3976mDNSlocal void AnswerNewLocalOnlyQuestion(mDNS *const m)
3977	{
3978	mDNSu32 slot;
3979	AuthGroup *ag;
3980	DNSQuestion *q = m->NewLocalOnlyQuestions;		// Grab the question we're going to answer
3981	m->NewLocalOnlyQuestions = q->next;				// Advance NewLocalOnlyQuestions to the next (if any)
3982
3983	debugf("AnswerNewLocalOnlyQuestion: Answering %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
3984
3985	if (m->CurrentQuestion)
3986		LogMsg("AnswerNewLocalOnlyQuestion ERROR m->CurrentQuestion already set: %##s (%s)",
3987			m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
3988	m->CurrentQuestion = q;		// Indicate which question we're answering, so we'll know if it gets deleted
3989
3990	if (m->CurrentRecord)
3991		LogMsg("AnswerNewLocalOnlyQuestion ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
3992
3993	// 1. First walk the LocalOnly records answering the LocalOnly question
3994	// 2. As LocalOnly questions should also be answered by any other Auth records local to the machine,
3995	//    walk the ResourceRecords list delivering the answers
3996	slot = AuthHashSlot(&q->qname);
3997	ag = AuthGroupForName(&m->rrauth, slot, q->qnamehash, &q->qname);
3998	if (ag)
3999		{
4000		m->CurrentRecord = ag->members;
4001		while (m->CurrentRecord && m->CurrentRecord != ag->NewLocalOnlyRecords)
4002			{
4003			AuthRecord *rr = m->CurrentRecord;
4004			m->CurrentRecord = rr->next;
4005			if (LocalOnlyRecordAnswersQuestion(rr, q))
4006				{
4007				AnswerLocalQuestionWithLocalAuthRecord(m, rr, mDNStrue);
4008				if (m->CurrentQuestion != q) break;		// If callback deleted q, then we're finished here
4009				}
4010			}
4011		}
4012
4013	if (m->CurrentQuestion == q)
4014		{
4015		m->CurrentRecord = m->ResourceRecords;
4016
4017		while (m->CurrentRecord && m->CurrentRecord != m->NewLocalRecords)
4018			{
4019			AuthRecord *rr = m->CurrentRecord;
4020			m->CurrentRecord = rr->next;
4021			if (ResourceRecordAnswersQuestion(&rr->resrec, q))
4022				{
4023				AnswerLocalQuestionWithLocalAuthRecord(m, rr, mDNStrue);
4024				if (m->CurrentQuestion != q) break;		// If callback deleted q, then we're finished here
4025				}
4026			}
4027		}
4028
4029	m->CurrentQuestion = mDNSNULL;
4030	m->CurrentRecord   = mDNSNULL;
4031	}
4032
4033mDNSlocal CacheEntity *GetCacheEntity(mDNS *const m, const CacheGroup *const PreserveCG)
4034	{
4035	CacheEntity *e = mDNSNULL;
4036
4037	if (m->lock_rrcache) { LogMsg("GetFreeCacheRR ERROR! Cache already locked!"); return(mDNSNULL); }
4038	m->lock_rrcache = 1;
4039
4040	// If we have no free records, ask the client layer to give us some more memory
4041	if (!m->rrcache_free && m->MainCallback)
4042		{
4043		if (m->rrcache_totalused != m->rrcache_size)
4044			LogMsg("GetFreeCacheRR: count mismatch: m->rrcache_totalused %lu != m->rrcache_size %lu",
4045				m->rrcache_totalused, m->rrcache_size);
4046
4047		// We don't want to be vulnerable to a malicious attacker flooding us with an infinite
4048		// number of bogus records so that we keep growing our cache until the machine runs out of memory.
4049		// To guard against this, if our cache grows above 512kB (approx 3168 records at 164 bytes each),
4050		// and we're actively using less than 1/32 of that cache, then we purge all the unused records
4051		// and recycle them, instead of allocating more memory.
4052		if (m->rrcache_size > 5000 && m->rrcache_size / 32 > m->rrcache_active)
4053			LogInfo("Possible denial-of-service attack in progress: m->rrcache_size %lu; m->rrcache_active %lu",
4054				m->rrcache_size, m->rrcache_active);
4055		else
4056			{
4057			mDNS_DropLockBeforeCallback();		// Allow client to legally make mDNS API calls from the callback
4058			m->MainCallback(m, mStatus_GrowCache);
4059			mDNS_ReclaimLockAfterCallback();	// Decrement mDNS_reentrancy to block mDNS API calls again
4060			}
4061		}
4062
4063	// If we still have no free records, recycle all the records we can.
4064	// Enumerating the entire cache is moderately expensive, so when we do it, we reclaim all the records we can in one pass.
4065	if (!m->rrcache_free)
4066		{
4067		mDNSu32 oldtotalused = m->rrcache_totalused;
4068		mDNSu32 slot;
4069		for (slot = 0; slot < CACHE_HASH_SLOTS; slot++)
4070			{
4071			CacheGroup **cp = &m->rrcache_hash[slot];
4072			while (*cp)
4073				{
4074				CacheRecord **rp = &(*cp)->members;
4075				while (*rp)
4076					{
4077					// Records that answer still-active questions are not candidates for recycling
4078					// Records that are currently linked into the CacheFlushRecords list may not be recycled, or we'll crash
4079					if ((*rp)->CRActiveQuestion || (*rp)->NextInCFList)
4080						rp=&(*rp)->next;
4081					else
4082						{
4083						CacheRecord *rr = *rp;
4084						*rp = (*rp)->next;			// Cut record from list
4085						ReleaseCacheRecord(m, rr);
4086						}
4087					}
4088				if ((*cp)->rrcache_tail != rp)
4089					verbosedebugf("GetFreeCacheRR: Updating rrcache_tail[%lu] from %p to %p", slot, (*cp)->rrcache_tail, rp);
4090				(*cp)->rrcache_tail = rp;
4091				if ((*cp)->members || (*cp)==PreserveCG) cp=&(*cp)->next;
4092				else ReleaseCacheGroup(m, cp);
4093				}
4094			}
4095		LogInfo("GetCacheEntity recycled %d records to reduce cache from %d to %d",
4096			oldtotalused - m->rrcache_totalused, oldtotalused, m->rrcache_totalused);
4097		}
4098
4099	if (m->rrcache_free)	// If there are records in the free list, take one
4100		{
4101		e = m->rrcache_free;
4102		m->rrcache_free = e->next;
4103		if (++m->rrcache_totalused >= m->rrcache_report)
4104			{
4105			LogInfo("RR Cache now using %ld objects", m->rrcache_totalused);
4106			if      (m->rrcache_report <  100) m->rrcache_report += 10;
4107			else if (m->rrcache_report < 1000) m->rrcache_report += 100;
4108			else                               m->rrcache_report += 1000;
4109			}
4110		mDNSPlatformMemZero(e, sizeof(*e));
4111		}
4112
4113	m->lock_rrcache = 0;
4114
4115	return(e);
4116	}
4117
4118mDNSlocal CacheRecord *GetCacheRecord(mDNS *const m, CacheGroup *cg, mDNSu16 RDLength)
4119	{
4120	CacheRecord *r = (CacheRecord *)GetCacheEntity(m, cg);
4121	if (r)
4122		{
4123		r->resrec.rdata = (RData*)&r->smallrdatastorage;	// By default, assume we're usually going to be using local storage
4124		if (RDLength > InlineCacheRDSize)			// If RDLength is too big, allocate extra storage
4125			{
4126			r->resrec.rdata = (RData*)mDNSPlatformMemAllocate(sizeofRDataHeader + RDLength);
4127			if (r->resrec.rdata) r->resrec.rdata->MaxRDLength = r->resrec.rdlength = RDLength;
4128			else { ReleaseCacheEntity(m, (CacheEntity*)r); r = mDNSNULL; }
4129			}
4130		}
4131	return(r);
4132	}
4133
4134mDNSlocal CacheGroup *GetCacheGroup(mDNS *const m, const mDNSu32 slot, const ResourceRecord *const rr)
4135	{
4136	mDNSu16 namelen = DomainNameLength(rr->name);
4137	CacheGroup *cg = (CacheGroup*)GetCacheEntity(m, mDNSNULL);
4138	if (!cg) { LogMsg("GetCacheGroup: Failed to allocate memory for %##s", rr->name->c); return(mDNSNULL); }
4139	cg->next         = m->rrcache_hash[slot];
4140	cg->namehash     = rr->namehash;
4141	cg->members      = mDNSNULL;
4142	cg->rrcache_tail = &cg->members;
4143	cg->name         = (domainname*)cg->namestorage;
4144	//LogMsg("GetCacheGroup: %-10s %d-byte cache name %##s",
4145	//	(namelen > InlineCacheGroupNameSize) ? "Allocating" : "Inline", namelen, rr->name->c);
4146	if (namelen > InlineCacheGroupNameSize) cg->name = mDNSPlatformMemAllocate(namelen);
4147	if (!cg->name)
4148		{
4149		LogMsg("GetCacheGroup: Failed to allocate name storage for %##s", rr->name->c);
4150		ReleaseCacheEntity(m, (CacheEntity*)cg);
4151		return(mDNSNULL);
4152		}
4153	AssignDomainName(cg->name, rr->name);
4154
4155	if (CacheGroupForRecord(m, slot, rr)) LogMsg("GetCacheGroup: Already have CacheGroup for %##s", rr->name->c);
4156	m->rrcache_hash[slot] = cg;
4157	if (CacheGroupForRecord(m, slot, rr) != cg) LogMsg("GetCacheGroup: Not finding CacheGroup for %##s", rr->name->c);
4158
4159	return(cg);
4160	}
4161
4162mDNSexport void mDNS_PurgeCacheResourceRecord(mDNS *const m, CacheRecord *rr)
4163	{
4164	if (m->mDNS_busy != m->mDNS_reentrancy+1)
4165		LogMsg("mDNS_PurgeCacheResourceRecord: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
4166	// Make sure we mark this record as thoroughly expired -- we don't ever want to give
4167	// a positive answer using an expired record (e.g. from an interface that has gone away).
4168	// We don't want to clear CRActiveQuestion here, because that would leave the record subject to
4169	// summary deletion without giving the proper callback to any questions that are monitoring it.
4170	// By setting UnansweredQueries to MaxUnansweredQueries we ensure it won't trigger any further expiration queries.
4171	rr->TimeRcvd          = m->timenow - mDNSPlatformOneSecond * 60;
4172	rr->UnansweredQueries = MaxUnansweredQueries;
4173	rr->resrec.rroriginalttl     = 0;
4174	SetNextCacheCheckTimeForRecord(m, rr);
4175	}
4176
4177mDNSexport mDNSs32 mDNS_TimeNow(const mDNS *const m)
4178	{
4179	mDNSs32 time;
4180	mDNSPlatformLock(m);
4181	if (m->mDNS_busy)
4182		{
4183		LogMsg("mDNS_TimeNow called while holding mDNS lock. This is incorrect. Code protected by lock should just use m->timenow.");
4184		if (!m->timenow) LogMsg("mDNS_TimeNow: m->mDNS_busy is %ld but m->timenow not set", m->mDNS_busy);
4185		}
4186
4187	if (m->timenow) time = m->timenow;
4188	else            time = mDNS_TimeNow_NoLock(m);
4189	mDNSPlatformUnlock(m);
4190	return(time);
4191	}
4192
4193// To avoid pointless CPU thrash, we use SetSPSProxyListChanged(X) to record the last interface that
4194// had its Sleep Proxy client list change, and defer to actual BPF reconfiguration to mDNS_Execute().
4195// (GetNextScheduledEvent() returns "now" when m->SPSProxyListChanged is set)
4196#define SetSPSProxyListChanged(X) do { \
4197	if (m->SPSProxyListChanged && m->SPSProxyListChanged != (X)) mDNSPlatformUpdateProxyList(m, m->SPSProxyListChanged); \
4198	m->SPSProxyListChanged = (X); } while(0)
4199
4200// Called from mDNS_Execute() to expire stale proxy records
4201mDNSlocal void CheckProxyRecords(mDNS *const m, AuthRecord *list)
4202	{
4203	m->CurrentRecord = list;
4204	while (m->CurrentRecord)
4205		{
4206		AuthRecord *rr = m->CurrentRecord;
4207		if (rr->resrec.RecordType != kDNSRecordTypeDeregistering && rr->WakeUp.HMAC.l[0])
4208			{
4209			// If m->SPSSocket is NULL that means we're not acting as a sleep proxy any more,
4210			// so we need to cease proxying for *all* records we may have, expired or not.
4211			if (m->SPSSocket && m->timenow - rr->TimeExpire < 0)	// If proxy record not expired yet, update m->NextScheduledSPS
4212				{
4213				if (m->NextScheduledSPS - rr->TimeExpire > 0)
4214					m->NextScheduledSPS = rr->TimeExpire;
4215				}
4216			else													// else proxy record expired, so remove it
4217				{
4218				LogSPS("CheckProxyRecords: Removing %d H-MAC %.6a I-MAC %.6a %d %s",
4219					m->ProxyRecords, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, rr->WakeUp.seq, ARDisplayString(m, rr));
4220				SetSPSProxyListChanged(rr->resrec.InterfaceID);
4221				mDNS_Deregister_internal(m, rr, mDNS_Dereg_normal);
4222				// Don't touch rr after this -- memory may have been free'd
4223				}
4224			}
4225		// Mustn't advance m->CurrentRecord until *after* mDNS_Deregister_internal, because
4226		// new records could have been added to the end of the list as a result of that call.
4227		if (m->CurrentRecord == rr) // If m->CurrentRecord was not advanced for us, do it now
4228			m->CurrentRecord = rr->next;
4229		}
4230	}
4231
4232mDNSlocal void CheckRmvEventsForLocalRecords(mDNS *const m)
4233	{
4234	while (m->CurrentRecord)
4235		{
4236		AuthRecord *rr = m->CurrentRecord;
4237		if (rr->AnsweredLocalQ && rr->resrec.RecordType == kDNSRecordTypeDeregistering)
4238			{
4239			debugf("CheckRmvEventsForLocalRecords: Generating local RMV events for %s", ARDisplayString(m, rr));
4240			rr->resrec.RecordType = kDNSRecordTypeShared;
4241			AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse);
4242			if (m->CurrentRecord == rr)	// If rr still exists in list, restore its state now
4243				{
4244				rr->resrec.RecordType = kDNSRecordTypeDeregistering;
4245				rr->AnsweredLocalQ = mDNSfalse;
4246				// SendResponses normally calls CompleteDeregistration after sending goodbyes.
4247				// For LocalOnly records, we don't do that and hence we need to do that here.
4248				if (RRLocalOnly(rr)) CompleteDeregistration(m, rr);
4249				}
4250			}
4251		if (m->CurrentRecord == rr)		// If m->CurrentRecord was not auto-advanced, do it ourselves now
4252			m->CurrentRecord = rr->next;
4253		}
4254	}
4255
4256mDNSlocal void TimeoutQuestions(mDNS *const m)
4257	{
4258	m->NextScheduledStopTime = m->timenow + 0x3FFFFFFF;
4259	if (m->CurrentQuestion)
4260		LogMsg("TimeoutQuestions ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c,
4261			DNSTypeName(m->CurrentQuestion->qtype));
4262	m->CurrentQuestion = m->Questions;
4263	while (m->CurrentQuestion)
4264		{
4265		DNSQuestion *const q = m->CurrentQuestion;
4266		if (q->StopTime)
4267			{
4268			if (m->timenow - q->StopTime >= 0)
4269				{
4270				LogInfo("TimeoutQuestions: question %##s timed out, time %d", q->qname.c, m->timenow - q->StopTime);
4271				GenerateNegativeResponse(m);
4272				if (m->CurrentQuestion == q) q->StopTime = 0;
4273				}
4274			else
4275				{
4276				if (m->NextScheduledStopTime - q->StopTime > 0)
4277					m->NextScheduledStopTime = q->StopTime;
4278				}
4279			}
4280		// If m->CurrentQuestion wasn't modified out from under us, advance it now
4281		// We can't do this at the start of the loop because GenerateNegativeResponse
4282		// depends on having m->CurrentQuestion point to the right question
4283		if (m->CurrentQuestion == q)
4284			m->CurrentQuestion = q->next;
4285		}
4286	m->CurrentQuestion = mDNSNULL;
4287	}
4288
4289mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
4290	{
4291	mDNS_Lock(m);	// Must grab lock before trying to read m->timenow
4292
4293	if (m->timenow - m->NextScheduledEvent >= 0)
4294		{
4295		int i;
4296		AuthRecord *head, *tail;
4297		mDNSu32 slot;
4298		AuthGroup *ag;
4299
4300		verbosedebugf("mDNS_Execute");
4301
4302		if (m->CurrentQuestion)
4303			LogMsg("mDNS_Execute: ERROR m->CurrentQuestion already set: %##s (%s)",
4304				m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
4305
4306		if (m->CurrentRecord)
4307			LogMsg("mDNS_Execute: ERROR m->CurrentRecord already set: %s", ARDisplayString(m, m->CurrentRecord));
4308
4309		// 1. If we're past the probe suppression time, we can clear it
4310		if (m->SuppressProbes && m->timenow - m->SuppressProbes >= 0) m->SuppressProbes = 0;
4311
4312		// 2. If it's been more than ten seconds since the last probe failure, we can clear the counter
4313		if (m->NumFailedProbes && m->timenow - m->ProbeFailTime >= mDNSPlatformOneSecond * 10) m->NumFailedProbes = 0;
4314
4315		// 3. Purge our cache of stale old records
4316		if (m->rrcache_size && m->timenow - m->NextCacheCheck >= 0)
4317			{
4318			mDNSu32 numchecked = 0;
4319			m->NextCacheCheck = m->timenow + 0x3FFFFFFF;
4320			for (slot = 0; slot < CACHE_HASH_SLOTS; slot++)
4321				{
4322				if (m->timenow - m->rrcache_nextcheck[slot] >= 0)
4323					{
4324					CacheGroup **cp = &m->rrcache_hash[slot];
4325					m->rrcache_nextcheck[slot] = m->timenow + 0x3FFFFFFF;
4326					while (*cp)
4327						{
4328						debugf("m->NextCacheCheck %4d Slot %3d %##s", numchecked, slot, *cp ? (*cp)->name : (domainname*)"\x04NULL");
4329						numchecked++;
4330						CheckCacheExpiration(m, slot, *cp);
4331						if ((*cp)->members) cp=&(*cp)->next;
4332						else ReleaseCacheGroup(m, cp);
4333						}
4334					}
4335				// Even if we didn't need to actually check this slot yet, still need to
4336				// factor its nextcheck time into our overall NextCacheCheck value
4337				if (m->NextCacheCheck - m->rrcache_nextcheck[slot] > 0)
4338					m->NextCacheCheck = m->rrcache_nextcheck[slot];
4339				}
4340			debugf("m->NextCacheCheck %4d checked, next in %d", numchecked, m->NextCacheCheck - m->timenow);
4341			}
4342
4343		if (m->timenow - m->NextScheduledSPS >= 0)
4344			{
4345			m->NextScheduledSPS = m->timenow + 0x3FFFFFFF;
4346			CheckProxyRecords(m, m->DuplicateRecords);	// Clear m->DuplicateRecords first, then m->ResourceRecords
4347			CheckProxyRecords(m, m->ResourceRecords);
4348			}
4349
4350		SetSPSProxyListChanged(mDNSNULL);		// Perform any deferred BPF reconfiguration now
4351
4352		// Clear AnnounceOwner if necessary. (Do this *before* SendQueries() and SendResponses().)
4353		if (m->AnnounceOwner && m->timenow - m->AnnounceOwner >= 0) m->AnnounceOwner = 0;
4354
4355		if (m->DelaySleep && m->timenow - m->DelaySleep >= 0)
4356			{
4357			m->DelaySleep = 0;
4358			if (m->SleepState == SleepState_Transferring)
4359				{
4360				LogSPS("Re-sleep delay passed; now checking for Sleep Proxy Servers");
4361				BeginSleepProcessing(m);
4362				}
4363			}
4364
4365		// 4. See if we can answer any of our new local questions from the cache
4366		for (i=0; m->NewQuestions && i<1000; i++)
4367			{
4368			if (m->NewQuestions->DelayAnswering && m->timenow - m->NewQuestions->DelayAnswering < 0) break;
4369			AnswerNewQuestion(m);
4370			}
4371		if (i >= 1000) LogMsg("mDNS_Execute: AnswerNewQuestion exceeded loop limit");
4372
4373		// Make sure we deliver *all* local RMV events, and clear the corresponding rr->AnsweredLocalQ flags, *before*
4374		// we begin generating *any* new ADD events in the m->NewLocalOnlyQuestions and m->NewLocalRecords loops below.
4375		for (i=0; i<1000 && m->LocalRemoveEvents; i++)
4376			{
4377			m->LocalRemoveEvents = mDNSfalse;
4378			m->CurrentRecord = m->ResourceRecords;
4379			CheckRmvEventsForLocalRecords(m);
4380			// Walk the LocalOnly records and deliver the RMV events
4381			for (slot = 0; slot < AUTH_HASH_SLOTS; slot++)
4382				for (ag = m->rrauth.rrauth_hash[slot]; ag; ag = ag->next)
4383					{
4384					m->CurrentRecord = ag->members;
4385					if (m->CurrentRecord) CheckRmvEventsForLocalRecords(m);
4386					}
4387			}
4388
4389		if (i >= 1000) LogMsg("mDNS_Execute: m->LocalRemoveEvents exceeded loop limit");
4390
4391		for (i=0; m->NewLocalOnlyQuestions && i<1000; i++) AnswerNewLocalOnlyQuestion(m);
4392		if (i >= 1000) LogMsg("mDNS_Execute: AnswerNewLocalOnlyQuestion exceeded loop limit");
4393
4394		head = tail = mDNSNULL;
4395		for (i=0; i<1000 && m->NewLocalRecords && m->NewLocalRecords != head; i++)
4396			{
4397			AuthRecord *rr = m->NewLocalRecords;
4398			m->NewLocalRecords = m->NewLocalRecords->next;
4399			if (LocalRecordReady(rr))
4400				{
4401				debugf("mDNS_Execute: Delivering Add event with LocalAuthRecord %s", ARDisplayString(m, rr));
4402				AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNStrue);
4403				}
4404			else if (!rr->next)
4405				{
4406				// If we have just one record that is not ready, we don't have to unlink and
4407				// reinsert. As the NewLocalRecords will be NULL for this case, the loop will
4408				// terminate and set the NewLocalRecords to rr.
4409				debugf("mDNS_Execute: Just one LocalAuthRecord %s, breaking out of the loop early", ARDisplayString(m, rr));
4410				if (head != mDNSNULL || m->NewLocalRecords != mDNSNULL)
4411					LogMsg("mDNS_Execute: ERROR!!: head %p, NewLocalRecords %p", head, m->NewLocalRecords);
4412
4413				head = rr;
4414				}
4415			else
4416				{
4417				AuthRecord **p = &m->ResourceRecords;	// Find this record in our list of active records
4418				debugf("mDNS_Execute: Skipping LocalAuthRecord %s", ARDisplayString(m, rr));
4419				// if this is the first record we are skipping, move to the end of the list.
4420				// if we have already skipped records before, append it at the end.
4421				while (*p && *p != rr) p=&(*p)->next;
4422				if (*p) *p = rr->next;					// Cut this record from the list
4423				else { LogMsg("mDNS_Execute: ERROR!! Cannot find record %s in ResourceRecords list", ARDisplayString(m, rr)); break; }
4424				if (!head)
4425					{
4426					while (*p) p=&(*p)->next;
4427					*p = rr;
4428					head = tail = rr;
4429					}
4430				else
4431					{
4432					tail->next = rr;
4433					tail = rr;
4434					}
4435				rr->next = mDNSNULL;
4436				}
4437			}
4438		m->NewLocalRecords = head;
4439		debugf("mDNS_Execute: Setting NewLocalRecords to %s", (head ? ARDisplayString(m, head) : "NULL"));
4440
4441		if (i >= 1000) LogMsg("mDNS_Execute: m->NewLocalRecords exceeded loop limit");
4442
4443		// Check to see if we have any new LocalOnly/P2P records to examine for delivering
4444		// to our local questions
4445		if (m->NewLocalOnlyRecords)
4446			{
4447			m->NewLocalOnlyRecords = mDNSfalse;
4448			for (slot = 0; slot < AUTH_HASH_SLOTS; slot++)
4449				for (ag = m->rrauth.rrauth_hash[slot]; ag; ag = ag->next)
4450					{
4451					for (i=0; i<100 && ag->NewLocalOnlyRecords; i++)
4452						{
4453						AuthRecord *rr = ag->NewLocalOnlyRecords;
4454						ag->NewLocalOnlyRecords = ag->NewLocalOnlyRecords->next;
4455						// LocalOnly records should always be ready as they never probe
4456						if (LocalRecordReady(rr))
4457							{
4458							debugf("mDNS_Execute: Delivering Add event with LocalAuthRecord %s", ARDisplayString(m, rr));
4459							AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNStrue);
4460							}
4461						else LogMsg("mDNS_Execute: LocalOnlyRecord %s not ready", ARDisplayString(m, rr));
4462						}
4463					// We limit about 100 per AuthGroup that can be serviced at a time
4464					if (i >= 100) LogMsg("mDNS_Execute: ag->NewLocalOnlyRecords exceeded loop limit");
4465					}
4466			}
4467
4468		// 5. Some questions may have picked a new DNS server and the cache may answer these questions now.
4469		AnswerQuestionsForDNSServerChanges(m);
4470
4471		// 6. See what packets we need to send
4472		if (m->mDNSPlatformStatus != mStatus_NoError || (m->SleepState == SleepState_Sleeping))
4473			DiscardDeregistrations(m);
4474		if (m->mDNSPlatformStatus == mStatus_NoError && (m->SuppressSending == 0 || m->timenow - m->SuppressSending >= 0))
4475			{
4476			// If the platform code is ready, and we're not suppressing packet generation right now
4477			// then send our responses, probes, and questions.
4478			// We check the cache first, because there might be records close to expiring that trigger questions to refresh them.
4479			// We send queries next, because there might be final-stage probes that complete their probing here, causing
4480			// them to advance to announcing state, and we want those to be included in any announcements we send out.
4481			// Finally, we send responses, including the previously mentioned records that just completed probing.
4482			m->SuppressSending = 0;
4483
4484			// 7. Send Query packets. This may cause some probing records to advance to announcing state
4485			if (m->timenow - m->NextScheduledQuery >= 0 || m->timenow - m->NextScheduledProbe >= 0) SendQueries(m);
4486			if (m->timenow - m->NextScheduledQuery >= 0)
4487				{
4488				DNSQuestion *q;
4489				LogMsg("mDNS_Execute: SendQueries didn't send all its queries (%d - %d = %d) will try again in one second",
4490					m->timenow, m->NextScheduledQuery, m->timenow - m->NextScheduledQuery);
4491				m->NextScheduledQuery = m->timenow + mDNSPlatformOneSecond;
4492				for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
4493					if (ActiveQuestion(q) && m->timenow - NextQSendTime(q) >= 0)
4494						LogMsg("mDNS_Execute: SendQueries didn't send %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
4495				}
4496			if (m->timenow - m->NextScheduledProbe >= 0)
4497				{
4498				LogMsg("mDNS_Execute: SendQueries didn't send all its probes (%d - %d = %d) will try again in one second",
4499					m->timenow, m->NextScheduledProbe, m->timenow - m->NextScheduledProbe);
4500				m->NextScheduledProbe = m->timenow + mDNSPlatformOneSecond;
4501				}
4502
4503			// 8. Send Response packets, including probing records just advanced to announcing state
4504			if (m->timenow - m->NextScheduledResponse >= 0) SendResponses(m);
4505			if (m->timenow - m->NextScheduledResponse >= 0)
4506				{
4507				LogMsg("mDNS_Execute: SendResponses didn't send all its responses; will try again in one second");
4508				m->NextScheduledResponse = m->timenow + mDNSPlatformOneSecond;
4509				}
4510			}
4511
4512		// Clear RandomDelay values, ready to pick a new different value next time
4513		m->RandomQueryDelay     = 0;
4514		m->RandomReconfirmDelay = 0;
4515
4516		if (m->NextScheduledStopTime && m->timenow - m->NextScheduledStopTime >= 0) TimeoutQuestions(m);
4517#ifndef UNICAST_DISABLED
4518		if (m->NextSRVUpdate && m->timenow - m->NextSRVUpdate >= 0) UpdateAllSRVRecords(m);
4519		if (m->timenow - m->NextScheduledNATOp >= 0) CheckNATMappings(m);
4520		if (m->timenow - m->NextuDNSEvent >= 0) uDNS_Tasks(m);
4521#endif
4522		}
4523
4524	// Note about multi-threaded systems:
4525	// On a multi-threaded system, some other thread could run right after the mDNS_Unlock(),
4526	// performing mDNS API operations that change our next scheduled event time.
4527	//
4528	// On multi-threaded systems (like the current Windows implementation) that have a single main thread
4529	// calling mDNS_Execute() (and other threads allowed to call mDNS API routines) it is the responsibility
4530	// of the mDNSPlatformUnlock() routine to signal some kind of stateful condition variable that will
4531	// signal whatever blocking primitive the main thread is using, so that it will wake up and execute one
4532	// more iteration of its loop, and immediately call mDNS_Execute() again. The signal has to be stateful
4533	// in the sense that if the main thread has not yet entered its blocking primitive, then as soon as it
4534	// does, the state of the signal will be noticed, causing the blocking primitive to return immediately
4535	// without blocking. This avoids the race condition between the signal from the other thread arriving
4536	// just *before* or just *after* the main thread enters the blocking primitive.
4537	//
4538	// On multi-threaded systems (like the current Mac OS 9 implementation) that are entirely timer-driven,
4539	// with no main mDNS_Execute() thread, it is the responsibility of the mDNSPlatformUnlock() routine to
4540	// set the timer according to the m->NextScheduledEvent value, and then when the timer fires, the timer
4541	// callback function should call mDNS_Execute() (and ignore the return value, which may already be stale
4542	// by the time it gets to the timer callback function).
4543
4544	mDNS_Unlock(m);		// Calling mDNS_Unlock is what gives m->NextScheduledEvent its new value
4545	return(m->NextScheduledEvent);
4546	}
4547
4548mDNSlocal void SuspendLLQs(mDNS *m)
4549	{
4550	DNSQuestion *q;
4551	for (q = m->Questions; q; q = q->next)
4552		if (ActiveQuestion(q) && !mDNSOpaque16IsZero(q->TargetQID) && q->LongLived && q->state == LLQ_Established)
4553			{ q->ReqLease = 0; sendLLQRefresh(m, q); }
4554	}
4555
4556mDNSlocal mDNSBool QuestionHasLocalAnswers(mDNS *const m, DNSQuestion *q)
4557	{
4558	AuthRecord *rr;
4559	mDNSu32 slot;
4560	AuthGroup *ag;
4561
4562	slot = AuthHashSlot(&q->qname);
4563	ag = AuthGroupForName(&m->rrauth, slot, q->qnamehash, &q->qname);
4564	if (ag)
4565		{
4566		for (rr = ag->members; rr; rr=rr->next)
4567			// Filter the /etc/hosts records - LocalOnly, Unique, A/AAAA/CNAME
4568			if (LORecordAnswersAddressType(rr) && LocalOnlyRecordAnswersQuestion(rr, q))
4569				{
4570				LogInfo("QuestionHasLocalAnswers: Question %p %##s (%s) has local answer %s", q, q->qname.c, DNSTypeName(q->qtype), ARDisplayString(m, rr));
4571				return mDNStrue;
4572				}
4573		}
4574	return mDNSfalse;
4575	}
4576
4577// ActivateUnicastQuery() is called from three places:
4578// 1. When a new question is created
4579// 2. On wake from sleep
4580// 3. When the DNS configuration changes
4581// In case 1 we don't want to mess with our established ThisQInterval and LastQTime (ScheduleImmediately is false)
4582// In cases 2 and 3 we do want to cause the question to be resent immediately (ScheduleImmediately is true)
4583mDNSlocal void ActivateUnicastQuery(mDNS *const m, DNSQuestion *const question, mDNSBool ScheduleImmediately)
4584	{
4585	// For now this AutoTunnel stuff is specific to Mac OS X.
4586	// In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer
4587#if APPLE_OSX_mDNSResponder
4588	// Even though BTMM client tunnels are only useful for AAAA queries, we need to treat v4 and v6 queries equally.
4589	// Otherwise we can get the situation where the A query completes really fast (with an NXDOMAIN result) and the
4590	// caller then gives up waiting for the AAAA result while we're still in the process of setting up the tunnel.
4591	// To level the playing field, we block both A and AAAA queries while tunnel setup is in progress, and then
4592	// returns results for both at the same time. If we are looking for the _autotunnel6 record, then skip this logic
4593	// as this would trigger looking up _autotunnel6._autotunnel6 and end up failing the original query.
4594
4595	if (RRTypeIsAddressType(question->qtype) && PrivateQuery(question) &&
4596		!SameDomainLabel(question->qname.c, (const mDNSu8 *)"\x0c_autotunnel6")&& question->QuestionCallback != AutoTunnelCallback)
4597		{
4598		question->NoAnswer = NoAnswer_Suspended;
4599		AddNewClientTunnel(m, question);
4600		return;
4601		}
4602#endif // APPLE_OSX_mDNSResponder
4603
4604	if (!question->DuplicateOf)
4605		{
4606		debugf("ActivateUnicastQuery: %##s %s%s%s",
4607			question->qname.c, DNSTypeName(question->qtype), PrivateQuery(question) ? " (Private)" : "", ScheduleImmediately ? " ScheduleImmediately" : "");
4608		question->CNAMEReferrals = 0;
4609		if (question->nta) { CancelGetZoneData(m, question->nta); question->nta = mDNSNULL; }
4610		if (question->LongLived)
4611			{
4612			question->state = LLQ_InitialRequest;
4613			question->id = zeroOpaque64;
4614			question->servPort = zeroIPPort;
4615			if (question->tcp) { DisposeTCPConn(question->tcp); question->tcp = mDNSNULL; }
4616			}
4617		// If the question has local answers, then we don't want answers from outside
4618		if (ScheduleImmediately && !QuestionHasLocalAnswers(m, question))
4619			{
4620			question->ThisQInterval = InitialQuestionInterval;
4621			question->LastQTime     = m->timenow - question->ThisQInterval;
4622			SetNextQueryTime(m, question);
4623			}
4624		}
4625	}
4626
4627// Caller should hold the lock
4628mDNSexport void mDNSCoreRestartAddressQueries(mDNS *const m, mDNSBool SearchDomainsChanged, FlushCache flushCacheRecords,
4629	CallbackBeforeStartQuery BeforeStartCallback, void *context)
4630	{
4631	DNSQuestion *q;
4632	DNSQuestion *restart = mDNSNULL;
4633
4634	if (!m->mDNS_busy) LogMsg("mDNSCoreRestartAddressQueries: ERROR!! Lock not held");
4635
4636	// 1. Flush the cache records
4637	if (flushCacheRecords) flushCacheRecords(m);
4638
4639	// 2. Even though we may have purged the cache records above, before it can generate RMV event
4640	// we are going to stop the question. Hence we need to deliver the RMV event before we
4641	// stop the question.
4642	//
4643	// CurrentQuestion is used by RmvEventsForQuestion below. While delivering RMV events, the
4644	// application callback can potentially stop the current question (detected by CurrentQuestion) or
4645	// *any* other question which could be the next one that we may process here. RestartQuestion
4646	// points to the "next" question which will be automatically advanced in mDNS_StopQuery_internal
4647	// if the "next" question is stopped while the CurrentQuestion is stopped
4648
4649	if (m->RestartQuestion)
4650		LogMsg("mDNSCoreRestartAddressQueries: ERROR!! m->RestartQuestion already set: %##s (%s)",
4651			m->RestartQuestion->qname.c, DNSTypeName(m->RestartQuestion->qtype));
4652
4653	m->RestartQuestion = m->Questions;
4654	while (m->RestartQuestion)
4655		{
4656		q = m->RestartQuestion;
4657		m->RestartQuestion = q->next;
4658		// GetZoneData questions are referenced by other questions (original query that started the GetZoneData
4659		// question)  through their "nta" pointer. Normally when the original query stops, it stops the
4660		// GetZoneData question and also frees the memory (See CancelGetZoneData). If we stop the GetZoneData
4661		// question followed by the original query that refers to this GetZoneData question, we will end up
4662		// freeing the GetZoneData question and then start the "freed" question at the end.
4663
4664		if (IsGetZoneDataQuestion(q))
4665			{
4666			DNSQuestion *refq = q->next;
4667			LogInfo("mDNSCoreRestartAddressQueries: Skipping GetZoneDataQuestion %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
4668			// debug stuff, we just try to find the referencing question and don't do much with it
4669			while (refq)
4670				{
4671				if (q == &refq->nta->question)
4672					{
4673					LogInfo("mDNSCoreRestartAddressQueries: Question %p %##s (%s) referring to GetZoneDataQuestion %p, not stopping", refq, refq->qname.c, DNSTypeName(refq->qtype), q);
4674					}
4675				refq = refq->next;
4676				}
4677			continue;
4678			}
4679
4680		// This function is called when /etc/hosts changes and that could affect A, AAAA and CNAME queries
4681		if (q->qtype != kDNSType_A && q->qtype != kDNSType_AAAA && q->qtype != kDNSType_CNAME) continue;
4682
4683		// If the search domains did not change, then we restart all the queries. Otherwise, only
4684		// for queries for which we "might" have appended search domains ("might" because we may
4685		// find results before we apply search domains even though AppendSearchDomains is set to 1)
4686		if (!SearchDomainsChanged || q->AppendSearchDomains)
4687			{
4688			// NOTE: CacheRecordRmvEventsForQuestion will not generate RMV events for queries that have non-zero
4689			// LOAddressAnswers. Hence it is important that we call CacheRecordRmvEventsForQuestion before
4690			// LocalRecordRmvEventsForQuestion (which decrements LOAddressAnswers). Let us say that
4691			// /etc/hosts has an A Record for web.apple.com. Any queries for web.apple.com will be answered locally.
4692			// But this can't prevent a CNAME/AAAA query to not to be sent on the wire. When it is sent on the wire,
4693			// it could create cache entries. When we are restarting queries, we can't deliver the cache RMV events
4694			// for the original query using these cache entries as ADDs were never delivered using these cache
4695			// entries and hence this order is needed.
4696
4697			// If the query is suppressed, the RMV events won't be delivered
4698			if (!CacheRecordRmvEventsForQuestion(m, q)) { LogInfo("mDNSCoreRestartAddressQueries: Question deleted while delivering Cache Record RMV events"); continue; }
4699
4700			// SuppressQuery status does not affect questions that are answered using local records
4701			if (!LocalRecordRmvEventsForQuestion(m, q)) { LogInfo("mDNSCoreRestartAddressQueries: Question deleted while delivering Local Record RMV events"); continue; }
4702
4703			LogInfo("mDNSCoreRestartAddressQueries: Stop question %p %##s (%s), AppendSearchDomains %d, qnameOrig %p", q,
4704				q->qname.c, DNSTypeName(q->qtype), q->AppendSearchDomains, q->qnameOrig);
4705			mDNS_StopQuery_internal(m, q);
4706			// Reset state so that it looks like it was in the beginning i.e it should look at /etc/hosts, cache
4707			// and then search domains should be appended. At the beginning, qnameOrig was NULL.
4708			if (q->qnameOrig)
4709				{
4710				LogInfo("mDNSCoreRestartAddressQueries: qnameOrig %##s", q->qnameOrig);
4711				AssignDomainName(&q->qname, q->qnameOrig);
4712				mDNSPlatformMemFree(q->qnameOrig);
4713				q->qnameOrig = mDNSNULL;
4714				q->RetryWithSearchDomains = ApplySearchDomainsFirst(q) ? 1 : 0;
4715				}
4716			q->SearchListIndex = 0;
4717			q->next = restart;
4718			restart = q;
4719			}
4720		}
4721
4722	// 3. Callback before we start the query
4723	if (BeforeStartCallback) BeforeStartCallback(m, context);
4724
4725	// 4. Restart all the stopped queries
4726	while (restart)
4727		{
4728		q = restart;
4729		restart = restart->next;
4730		q->next = mDNSNULL;
4731		LogInfo("mDNSCoreRestartAddressQueries: Start question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
4732		mDNS_StartQuery_internal(m, q);
4733		}
4734	}
4735
4736mDNSexport void mDNSCoreRestartQueries(mDNS *const m)
4737	{
4738	DNSQuestion *q;
4739
4740#ifndef UNICAST_DISABLED
4741	// Retrigger all our uDNS questions
4742	if (m->CurrentQuestion)
4743		LogMsg("mDNSCoreRestartQueries: ERROR m->CurrentQuestion already set: %##s (%s)",
4744			m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
4745	m->CurrentQuestion = m->Questions;
4746	while (m->CurrentQuestion)
4747		{
4748		q = m->CurrentQuestion;
4749		m->CurrentQuestion = m->CurrentQuestion->next;
4750		if (!mDNSOpaque16IsZero(q->TargetQID) && ActiveQuestion(q)) ActivateUnicastQuery(m, q, mDNStrue);
4751		}
4752#endif
4753
4754	// Retrigger all our mDNS questions
4755	for (q = m->Questions; q; q=q->next)				// Scan our list of questions
4756		if (mDNSOpaque16IsZero(q->TargetQID) && ActiveQuestion(q))
4757			{
4758			q->ThisQInterval    = InitialQuestionInterval;	// MUST be > zero for an active question
4759			q->RequestUnicast   = 2;						// Set to 2 because is decremented once *before* we check it
4760			q->LastQTime        = m->timenow - q->ThisQInterval;
4761			q->RecentAnswerPkts = 0;
4762			ExpireDupSuppressInfo(q->DupSuppress, m->timenow);
4763			m->NextScheduledQuery = m->timenow;
4764			}
4765	}
4766
4767// ***************************************************************************
4768#if COMPILER_LIKES_PRAGMA_MARK
4769#pragma mark -
4770#pragma mark - Power Management (Sleep/Wake)
4771#endif
4772
4773mDNSexport void mDNS_UpdateAllowSleep(mDNS *const m)
4774	{
4775#ifndef IDLESLEEPCONTROL_DISABLED
4776	mDNSBool allowSleep = mDNStrue;
4777	char     reason[128];
4778
4779	reason[0] = 0;
4780
4781	if (m->SystemSleepOnlyIfWakeOnLAN)
4782		{
4783		// Don't sleep if we are a proxy for any services
4784		if (m->ProxyRecords)
4785			{
4786			allowSleep = mDNSfalse;
4787			mDNS_snprintf(reason, sizeof(reason), "sleep proxy for %d records", m->ProxyRecords);
4788			LogInfo("Sleep disabled because we are proxying %d records", m->ProxyRecords);
4789			}
4790
4791		if (allowSleep && mDNSCoreHaveAdvertisedMulticastServices(m))
4792			{
4793			// Scan the list of active interfaces
4794			NetworkInterfaceInfo *intf;
4795			for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
4796				{
4797				if (intf->McastTxRx && !intf->Loopback)
4798					{
4799					// Disallow sleep if this interface doesn't support NetWake
4800					if (!intf->NetWake)
4801						{
4802						allowSleep = mDNSfalse;
4803						mDNS_snprintf(reason, sizeof(reason), "%s does not support NetWake", intf->ifname);
4804						LogInfo("Sleep disabled because %s does not support NetWake", intf->ifname);
4805						break;
4806						}
4807
4808					// Disallow sleep if there is no sleep proxy server
4809					if (FindSPSInCache1(m, &intf->NetWakeBrowse, mDNSNULL, mDNSNULL) == mDNSNULL)
4810						{
4811						allowSleep = mDNSfalse;
4812						mDNS_snprintf(reason, sizeof(reason), "%s does not support NetWake", intf->ifname);
4813						LogInfo("Sleep disabled because %s has no sleep proxy", intf->ifname);
4814						break;
4815						}
4816					}
4817				}
4818			}
4819		}
4820
4821	// Call the platform code to enable/disable sleep
4822	mDNSPlatformSetAllowSleep(m, allowSleep, reason);
4823#endif /* !defined(IDLESLEEPCONTROL_DISABLED) */
4824	}
4825
4826mDNSlocal void SendSPSRegistrationForOwner(mDNS *const m, NetworkInterfaceInfo *const intf, const mDNSOpaque16 id, const OwnerOptData *const owner)
4827	{
4828	const int optspace = DNSOpt_Header_Space + DNSOpt_LeaseData_Space + DNSOpt_Owner_Space(&m->PrimaryMAC, &intf->MAC);
4829	const int sps = intf->NextSPSAttempt / 3;
4830	AuthRecord *rr;
4831
4832	if (!intf->SPSAddr[sps].type)
4833		{
4834		intf->NextSPSAttemptTime = m->timenow + mDNSPlatformOneSecond;
4835		if (m->NextScheduledSPRetry - intf->NextSPSAttemptTime > 0)
4836			m->NextScheduledSPRetry = intf->NextSPSAttemptTime;
4837		LogSPS("SendSPSRegistration: %s SPS %d (%d) %##s not yet resolved", intf<