<rdar://problem/7481776> Suppress logs for "A non-blocking socket operation could...
[people/sha0/mDNSResponder.git] / mDNSCore / mDNS.c
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 // Forward declarations
58 mDNSlocal void BeginSleepProcessing(mDNS *const m);
59 mDNSlocal void RetrySPSRegistrations(mDNS *const m);
60 mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAddr *EthAddr, mDNSOpaque48 *password);
61
62 // ***************************************************************************
63 #if COMPILER_LIKES_PRAGMA_MARK
64 #pragma mark - Program Constants
65 #endif
66
67 #define NO_HINFO 1
68
69
70 // Any records bigger than this are considered 'large' records
71 #define SmallRecordLimit 1024
72
73 #define kMaxUpdateCredits 10
74 #define kUpdateCreditRefreshInterval (mDNSPlatformOneSecond * 6)
75
76 mDNSexport const char *const mDNS_DomainTypeNames[] =
77         {
78          "b._dns-sd._udp.",             // Browse
79         "db._dns-sd._udp.",             // Default Browse
80         "lb._dns-sd._udp.",             // Automatic Browse
81          "r._dns-sd._udp.",             // Registration
82         "dr._dns-sd._udp."              // Default Registration
83         };
84
85 #ifdef UNICAST_DISABLED
86 #define uDNS_IsActiveQuery(q, u) mDNSfalse
87 #endif
88
89 // ***************************************************************************
90 #if COMPILER_LIKES_PRAGMA_MARK
91 #pragma mark -
92 #pragma mark - General Utility Functions
93 #endif
94
95 #define ActiveQuestion(Q) ((Q)->ThisQInterval > 0 && !(Q)->DuplicateOf)
96 #define TimeToSendThisQuestion(Q,time) (ActiveQuestion(Q) && (time) - ((Q)->LastQTime + (Q)->ThisQInterval) >= 0)
97
98 mDNSexport void SetNextQueryTime(mDNS *const m, const DNSQuestion *const q)
99         {
100         if (m->mDNS_busy != m->mDNS_reentrancy+1)
101                 LogMsg("SetNextQueryTime: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
102
103 #if ForceAlerts
104         if (m->mDNS_busy != m->mDNS_reentrancy+1) *(long*)0 = 0;
105 #endif
106
107         if (ActiveQuestion(q))
108                 {
109                 mDNSs32 sendtime = q->LastQTime + q->ThisQInterval;
110
111                 // Don't allow sendtime to be earlier than SuppressStdPort53Queries
112                 if (!mDNSOpaque16IsZero(q->TargetQID) && !q->LongLived && m->SuppressStdPort53Queries && (sendtime - m->SuppressStdPort53Queries < 0))
113                         sendtime = m->SuppressStdPort53Queries;
114
115                 if (m->NextScheduledQuery - sendtime > 0)
116                         m->NextScheduledQuery = sendtime;
117                 }
118         }
119
120 mDNSexport CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name)
121         {
122         CacheGroup *cg;
123         for (cg = m->rrcache_hash[slot]; cg; cg=cg->next)
124                 if (cg->namehash == namehash && SameDomainName(cg->name, name))
125                         break;
126         return(cg);
127         }
128
129 mDNSlocal CacheGroup *CacheGroupForRecord(const mDNS *const m, const mDNSu32 slot, const ResourceRecord *const rr)
130         {
131         return(CacheGroupForName(m, slot, rr->namehash, rr->name));
132         }
133
134 mDNSexport mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr)
135         {
136         NetworkInterfaceInfo *intf;
137
138         if (addr->type == mDNSAddrType_IPv4)
139                 {
140                 // Normally we resist touching the NotAnInteger fields, but here we're doing tricky bitwise masking so we make an exception
141                 if (mDNSv4AddressIsLinkLocal(&addr->ip.v4)) return(mDNStrue);
142                 for (intf = m->HostInterfaces; intf; intf = intf->next)
143                         if (intf->ip.type == addr->type && intf->InterfaceID == InterfaceID && intf->McastTxRx)
144                                 if (((intf->ip.ip.v4.NotAnInteger ^ addr->ip.v4.NotAnInteger) & intf->mask.ip.v4.NotAnInteger) == 0)
145                                         return(mDNStrue);
146                 }
147
148         if (addr->type == mDNSAddrType_IPv6)
149                 {
150                 if (mDNSv6AddressIsLinkLocal(&addr->ip.v4)) return(mDNStrue);
151                 for (intf = m->HostInterfaces; intf; intf = intf->next)
152                         if (intf->ip.type == addr->type && intf->InterfaceID == InterfaceID && intf->McastTxRx)
153                                 if ((((intf->ip.ip.v6.l[0] ^ addr->ip.v6.l[0]) & intf->mask.ip.v6.l[0]) == 0) &&
154                                         (((intf->ip.ip.v6.l[1] ^ addr->ip.v6.l[1]) & intf->mask.ip.v6.l[1]) == 0) &&
155                                         (((intf->ip.ip.v6.l[2] ^ addr->ip.v6.l[2]) & intf->mask.ip.v6.l[2]) == 0) &&
156                                         (((intf->ip.ip.v6.l[3] ^ addr->ip.v6.l[3]) & intf->mask.ip.v6.l[3]) == 0))
157                                                 return(mDNStrue);
158                 }
159
160         return(mDNSfalse);
161         }
162
163 mDNSlocal NetworkInterfaceInfo *FirstInterfaceForID(mDNS *const m, const mDNSInterfaceID InterfaceID)
164         {
165         NetworkInterfaceInfo *intf = m->HostInterfaces;
166         while (intf && intf->InterfaceID != InterfaceID) intf = intf->next;
167         return(intf);
168         }
169
170 mDNSexport char *InterfaceNameForID(mDNS *const m, const mDNSInterfaceID InterfaceID)
171         {
172         NetworkInterfaceInfo *intf = FirstInterfaceForID(m, InterfaceID);
173         return(intf ? intf->ifname : mDNSNULL);
174         }
175
176 // For a single given DNSQuestion, deliver an add/remove result for the single given AuthRecord
177 // Used by AnswerAllLocalQuestionsWithLocalAuthRecord() and AnswerNewLocalOnlyQuestion()
178 mDNSlocal void AnswerLocalQuestionWithLocalAuthRecord(mDNS *const m, DNSQuestion *q, AuthRecord *rr, QC_result AddRecord)
179         {
180         // We should not be delivering results for record types Unregistered, Deregistering, and (unverified) Unique
181         if (!(rr->resrec.RecordType & kDNSRecordTypeActiveMask))
182                 {
183                 LogMsg("AnswerLocalQuestionWithLocalAuthRecord: *NOT* delivering %s event for local record type %X %s",
184                         AddRecord ? "Add" : "Rmv", rr->resrec.RecordType, ARDisplayString(m, rr));
185                 return;
186                 }
187
188         // Indicate that we've given at least one positive answer for this record, so we should be prepared to send a goodbye for it
189         if (AddRecord) rr->AnsweredLocalQ = mDNStrue;
190         mDNS_DropLockBeforeCallback();          // Allow client to legally make mDNS API calls from the callback
191         if (q->QuestionCallback && !q->NoAnswer)
192                 {
193                 q->CurrentAnswers += AddRecord ? 1 : -1;
194                 q->QuestionCallback(m, q, &rr->resrec, AddRecord);
195                 }
196         mDNS_ReclaimLockAfterCallback();        // Decrement mDNS_reentrancy to block mDNS API calls again
197         }
198
199 // When a new local AuthRecord is created or deleted, AnswerAllLocalQuestionsWithLocalAuthRecord() runs though
200 // all our local questions (both LocalOnlyQuestions and mDNSInterface_Any questions) delivering answers to each,
201 // stopping if it reaches a NewLocalOnlyQuestion -- brand-new questions are handled by AnswerNewLocalOnlyQuestion().
202 // If the AuthRecord is marked mDNSInterface_LocalOnly, then we also deliver it to any other questions we have using mDNSInterface_Any.
203 // Used by the m->NewLocalRecords loop in mDNS_Execute(), and by mDNS_Deregister_internal()
204 mDNSlocal void AnswerAllLocalQuestionsWithLocalAuthRecord(mDNS *const m, AuthRecord *rr, QC_result AddRecord)
205         {
206         if (m->CurrentQuestion)
207                 LogMsg("AnswerAllLocalQuestionsWithLocalAuthRecord ERROR m->CurrentQuestion already set: %##s (%s)",
208                         m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
209
210         m->CurrentQuestion = m->LocalOnlyQuestions;
211         while (m->CurrentQuestion && m->CurrentQuestion != m->NewLocalOnlyQuestions)
212                 {
213                 DNSQuestion *q = m->CurrentQuestion;
214                 m->CurrentQuestion = q->next;
215                 if (ResourceRecordAnswersQuestion(&rr->resrec, q))
216                         AnswerLocalQuestionWithLocalAuthRecord(m, q, rr, AddRecord);                    // MUST NOT dereference q again
217                 }
218
219         // If this AuthRecord is marked LocalOnly, then we want to deliver it to all local 'mDNSInterface_Any' questions
220         if (rr->resrec.InterfaceID == mDNSInterface_LocalOnly)
221                 {
222                 m->CurrentQuestion = m->Questions;
223                 while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
224                         {
225                         DNSQuestion *q = m->CurrentQuestion;
226                         m->CurrentQuestion = q->next;
227                         if (ResourceRecordAnswersQuestion(&rr->resrec, q))
228                                 AnswerLocalQuestionWithLocalAuthRecord(m, q, rr, AddRecord);            // MUST NOT dereference q again
229                         }
230                 }
231
232         m->CurrentQuestion = mDNSNULL;
233         }
234
235 // ***************************************************************************
236 #if COMPILER_LIKES_PRAGMA_MARK
237 #pragma mark -
238 #pragma mark - Resource Record Utility Functions
239 #endif
240
241 #define RRTypeIsAddressType(T) ((T) == kDNSType_A || (T) == kDNSType_AAAA)
242
243 #define ResourceRecordIsValidAnswer(RR) ( ((RR)->             resrec.RecordType & kDNSRecordTypeActiveMask)  && \
244                 ((RR)->Additional1 == mDNSNULL || ((RR)->Additional1->resrec.RecordType & kDNSRecordTypeActiveMask)) && \
245                 ((RR)->Additional2 == mDNSNULL || ((RR)->Additional2->resrec.RecordType & kDNSRecordTypeActiveMask)) && \
246                 ((RR)->DependentOn == mDNSNULL || ((RR)->DependentOn->resrec.RecordType & kDNSRecordTypeActiveMask))  )
247
248 #define ResourceRecordIsValidInterfaceAnswer(RR, INTID) \
249         (ResourceRecordIsValidAnswer(RR) && \
250         ((RR)->resrec.InterfaceID == mDNSInterface_Any || (RR)->resrec.InterfaceID == (INTID)))
251
252 #define DefaultProbeCountForTypeUnique ((mDNSu8)3)
253 #define DefaultProbeCountForRecordType(X)      ((X) == kDNSRecordTypeUnique ? DefaultProbeCountForTypeUnique : (mDNSu8)0)
254
255 #define InitialAnnounceCount ((mDNSu8)8)
256
257 // Note that the announce intervals use exponential backoff, doubling each time. The probe intervals do not.
258 // This means that because the announce interval is doubled after sending the first packet, the first
259 // observed on-the-wire inter-packet interval between announcements is actually one second.
260 // The half-second value here may be thought of as a conceptual (non-existent) half-second delay *before* the first packet is sent.
261 #define DefaultProbeIntervalForTypeUnique (mDNSPlatformOneSecond/4)
262 #define DefaultAnnounceIntervalForTypeShared (mDNSPlatformOneSecond/2)
263 #define DefaultAnnounceIntervalForTypeUnique (mDNSPlatformOneSecond/2)
264
265 #define DefaultAPIntervalForRecordType(X)  ((X) & (kDNSRecordTypeAdvisory | kDNSRecordTypeShared     ) ? DefaultAnnounceIntervalForTypeShared : \
266                                                                                         (X) & (kDNSRecordTypeUnique                              ) ? DefaultProbeIntervalForTypeUnique    : \
267                                                                                         (X) & (kDNSRecordTypeVerified | kDNSRecordTypeKnownUnique) ? DefaultAnnounceIntervalForTypeUnique : 0)
268
269 #define TimeToAnnounceThisRecord(RR,time) ((RR)->AnnounceCount && (time) - ((RR)->LastAPTime + (RR)->ThisAPInterval) >= 0)
270 #define TimeToSendThisRecord(RR,time) ((TimeToAnnounceThisRecord(RR,time) || (RR)->ImmedAnswer) && ResourceRecordIsValidAnswer(RR))
271 #define TicksTTL(RR) ((mDNSs32)(RR)->resrec.rroriginalttl * mDNSPlatformOneSecond)
272 #define RRExpireTime(RR) ((RR)->TimeRcvd + TicksTTL(RR))
273
274 #define MaxUnansweredQueries 4
275
276 // SameResourceRecordSignature returns true if two resources records have the same name, type, and class, and may be sent
277 // (or were received) on the same interface (i.e. if *both* records specify an interface, then it has to match).
278 // TTL and rdata may differ.
279 // This is used for cache flush management:
280 // When sending a unique record, all other records matching "SameResourceRecordSignature" must also be sent
281 // When receiving a unique record, all old cache records matching "SameResourceRecordSignature" are flushed
282
283 // SameResourceRecordNameClassInterface is functionally the same as SameResourceRecordSignature, except rrtype does not have to match
284
285 #define SameResourceRecordSignature(A,B) (A)->resrec.rrtype == (B)->resrec.rrtype && SameResourceRecordNameClassInterface((A),(B))
286
287 mDNSlocal mDNSBool SameResourceRecordNameClassInterface(const AuthRecord *const r1, const AuthRecord *const r2)
288         {
289         if (!r1) { LogMsg("SameResourceRecordSignature ERROR: r1 is NULL"); return(mDNSfalse); }
290         if (!r2) { LogMsg("SameResourceRecordSignature ERROR: r2 is NULL"); return(mDNSfalse); }
291         if (r1->resrec.InterfaceID &&
292                 r2->resrec.InterfaceID &&
293                 r1->resrec.InterfaceID != r2->resrec.InterfaceID) return(mDNSfalse);
294         return(mDNSBool)(
295                 r1->resrec.rrclass  == r2->resrec.rrclass &&
296                 r1->resrec.namehash == r2->resrec.namehash &&
297                 SameDomainName(r1->resrec.name, r2->resrec.name));
298         }
299
300 // PacketRRMatchesSignature behaves as SameResourceRecordSignature, except that types may differ if our
301 // authoratative record is unique (as opposed to shared). For unique records, we are supposed to have
302 // complete ownership of *all* types for this name, so *any* record type with the same name is a conflict.
303 // In addition, when probing we send our questions with the wildcard type kDNSQType_ANY,
304 // so a response of any type should match, even if it is not actually the type the client plans to use.
305
306 // For now, to make it easier to avoid false conflicts, we treat SPS Proxy records like shared records,
307 // and require the rrtypes to match for the rdata to be considered potentially conflicting
308 mDNSlocal mDNSBool PacketRRMatchesSignature(const CacheRecord *const pktrr, const AuthRecord *const authrr)
309         {
310         if (!pktrr)  { LogMsg("PacketRRMatchesSignature ERROR: pktrr is NULL"); return(mDNSfalse); }
311         if (!authrr) { LogMsg("PacketRRMatchesSignature ERROR: authrr is NULL"); return(mDNSfalse); }
312         if (pktrr->resrec.InterfaceID &&
313                 authrr->resrec.InterfaceID &&
314                 pktrr->resrec.InterfaceID != authrr->resrec.InterfaceID) return(mDNSfalse);
315         if (!(authrr->resrec.RecordType & kDNSRecordTypeUniqueMask) || authrr->WakeUp.HMAC.l[0])
316                 if (pktrr->resrec.rrtype != authrr->resrec.rrtype) return(mDNSfalse);
317         return(mDNSBool)(
318                 pktrr->resrec.rrclass == authrr->resrec.rrclass &&
319                 pktrr->resrec.namehash == authrr->resrec.namehash &&
320                 SameDomainName(pktrr->resrec.name, authrr->resrec.name));
321         }
322
323 // CacheRecord *ka is the CacheRecord from the known answer list in the query.
324 // This is the information that the requester believes to be correct.
325 // AuthRecord *rr is the answer we are proposing to give, if not suppressed.
326 // This is the information that we believe to be correct.
327 // We've already determined that we plan to give this answer on this interface
328 // (either the record is non-specific, or it is specific to this interface)
329 // so now we just need to check the name, type, class, rdata and TTL.
330 mDNSlocal mDNSBool ShouldSuppressKnownAnswer(const CacheRecord *const ka, const AuthRecord *const rr)
331         {
332         // If RR signature is different, or data is different, then don't suppress our answer
333         if (!IdenticalResourceRecord(&ka->resrec, &rr->resrec)) return(mDNSfalse);
334         
335         // If the requester's indicated TTL is less than half the real TTL,
336         // we need to give our answer before the requester's copy expires.
337         // If the requester's indicated TTL is at least half the real TTL,
338         // then we can suppress our answer this time.
339         // If the requester's indicated TTL is greater than the TTL we believe,
340         // then that's okay, and we don't need to do anything about it.
341         // (If two responders on the network are offering the same information,
342         // that's okay, and if they are offering the information with different TTLs,
343         // the one offering the lower TTL should defer to the one offering the higher TTL.)
344         return(mDNSBool)(ka->resrec.rroriginalttl >= rr->resrec.rroriginalttl / 2);
345         }
346
347 mDNSlocal void SetNextAnnounceProbeTime(mDNS *const m, const AuthRecord *const rr)
348         {
349         if (rr->resrec.RecordType == kDNSRecordTypeUnique)
350                 {
351                 //LogMsg("ProbeCount %d Next %ld %s", rr->ProbeCount, (rr->LastAPTime + rr->ThisAPInterval) - m->timenow, ARDisplayString(m, rr));
352                 if (m->NextScheduledProbe - (rr->LastAPTime + rr->ThisAPInterval) >= 0)
353                         m->NextScheduledProbe = (rr->LastAPTime + rr->ThisAPInterval);
354                 }
355         else if (rr->AnnounceCount && (ResourceRecordIsValidAnswer(rr) || rr->resrec.RecordType == kDNSRecordTypeDeregistering))
356                 {
357                 if (m->NextScheduledResponse - (rr->LastAPTime + rr->ThisAPInterval) >= 0)
358                         m->NextScheduledResponse = (rr->LastAPTime + rr->ThisAPInterval);
359                 }
360         }
361
362 mDNSlocal void InitializeLastAPTime(mDNS *const m, AuthRecord *const rr)
363         {
364         // For reverse-mapping Sleep Proxy PTR records, probe interval is one second
365         rr->ThisAPInterval = rr->AddressProxy.type ? mDNSPlatformOneSecond : DefaultAPIntervalForRecordType(rr->resrec.RecordType);
366
367         // To allow us to aggregate probes when a group of services are registered together,
368         // the first probe is delayed 1/4 second. This means the common-case behaviour is:
369         // 1/4 second wait; probe
370         // 1/4 second wait; probe
371         // 1/4 second wait; probe
372         // 1/4 second wait; announce (i.e. service is normally announced exactly one second after being registered)
373
374         if (rr->ProbeCount)
375                 {
376                 // If we have no probe suppression time set, or it is in the past, set it now
377                 if (m->SuppressProbes == 0 || m->SuppressProbes - m->timenow < 0)
378                         {
379                         m->SuppressProbes = NonZeroTime(m->timenow + DefaultProbeIntervalForTypeUnique);
380                         // If we already have a *probe* scheduled to go out sooner, then use that time to get better aggregation
381                         if (m->SuppressProbes - m->NextScheduledProbe >= 0)
382                                 m->SuppressProbes = m->NextScheduledProbe;
383                         // If we already have a *query* scheduled to go out sooner, then use that time to get better aggregation
384                         if (m->SuppressProbes - m->NextScheduledQuery >= 0)
385                                 m->SuppressProbes = m->NextScheduledQuery;
386                         }
387                 }
388
389         rr->LastAPTime      = m->SuppressProbes - rr->ThisAPInterval;
390         // Set LastMCTime to now, to inhibit multicast responses
391         // (no need to send additional multicast responses when we're announcing anyway)
392         rr->LastMCTime      = m->timenow;
393         rr->LastMCInterface = mDNSInterfaceMark;
394         
395         // If this is a record type that's not going to probe, then delay its first announcement so that
396         // it will go out synchronized with the first announcement for the other records that *are* probing.
397         // This is a minor performance tweak that helps keep groups of related records synchronized together.
398         // The addition of "interval / 2" is to make sure that, in the event that any of the probes are
399         // delayed by a few milliseconds, this announcement does not inadvertently go out *before* the probing is complete.
400         // When the probing is complete and those records begin to announce, these records will also be picked up and accelerated,
401         // because they will meet the criterion of being at least half-way to their scheduled announcement time.
402         if (rr->resrec.RecordType != kDNSRecordTypeUnique)
403                 rr->LastAPTime += DefaultProbeIntervalForTypeUnique * DefaultProbeCountForTypeUnique + rr->ThisAPInterval / 2;
404
405         // The exception is unique records that have already been verified and are just being updated
406         // via mDNS_Update() -- for these we want to announce the new value immediately, without delay.
407         if (rr->resrec.RecordType == kDNSRecordTypeVerified)
408                 rr->LastAPTime = m->timenow - rr->ThisAPInterval;
409
410         // For reverse-mapping Sleep Proxy PTR records we don't want to start probing instantly -- we
411         // wait one second to give the client a chance to go to sleep, and then start our ARP/NDP probing.
412         // After three probes one second apart with no answer, we conclude the client is now sleeping
413         // and we can begin broadcasting our announcements to take over ownership of that IP address.
414         // If we don't wait for the client to go to sleep, then when the client sees our ARP Announcements there's a risk
415         // (depending on the OS and networking stack it's using) that it might interpret it as a conflict and change its IP address.
416         if (rr->AddressProxy.type) rr->LastAPTime = m->timenow;
417
418         // Unsolicited Neighbor Advertisements (RFC 2461 Section 7.2.6) give us fast address cache updating,
419         // but some older IPv6 clients get confused by them, so for now we don't send them. Without Unsolicited
420         // Neighbor Advertisements we have to rely on Neighbor Unreachability Detection instead, which is slower.
421         // Given this, we'll do our best to wake for existing IPv6 connections, but we don't want to encourage
422         // new ones for sleeping clients, so we'll we send deletions for our SPS clients' AAAA records.
423         if (rr->WakeUp.HMAC.l[0] && rr->resrec.rrtype == kDNSType_AAAA)
424                 rr->LastAPTime = m->timenow - rr->ThisAPInterval + mDNSPlatformOneSecond * 10;
425         
426         SetNextAnnounceProbeTime(m, rr);
427         }
428
429 // Right now this only applies to mDNS (.local) services where the target host is always m->MulticastHostname
430 // Eventually we should unify this with GetServiceTarget() in uDNS.c
431 mDNSlocal void SetTargetToHostName(mDNS *const m, AuthRecord *const rr)
432         {
433         domainname *const target = GetRRDomainNameTarget(&rr->resrec);
434         const domainname *newname = &m->MulticastHostname;
435
436         if (!target) debugf("SetTargetToHostName: Don't know how to set the target of rrtype %d", rr->resrec.rrtype);
437
438         if (!(rr->ForceMCast || rr->resrec.InterfaceID == mDNSInterface_LocalOnly || IsLocalDomain(&rr->namestorage)))
439                 {
440                 const domainname *const n = GetServiceTarget(m, rr);
441                 if (n) newname = n;
442                 }
443
444         if (target && SameDomainName(target, newname))
445                 debugf("SetTargetToHostName: Target of %##s is already %##s", rr->resrec.name->c, target->c);
446         
447         if (target && !SameDomainName(target, newname))
448                 {
449                 AssignDomainName(target, newname);
450                 SetNewRData(&rr->resrec, mDNSNULL, 0);          // Update rdlength, rdestimate, rdatahash
451                 
452                 // If we're in the middle of probing this record, we need to start again,
453                 // because changing its rdata may change the outcome of the tie-breaker.
454                 // (If the record type is kDNSRecordTypeUnique (unconfirmed unique) then DefaultProbeCountForRecordType is non-zero.)
455                 rr->ProbeCount     = DefaultProbeCountForRecordType(rr->resrec.RecordType);
456
457                 // If we've announced this record, we really should send a goodbye packet for the old rdata before
458                 // changing to the new rdata. However, in practice, we only do SetTargetToHostName for unique records,
459                 // so when we announce them we'll set the kDNSClass_UniqueRRSet and clear any stale data that way.
460                 if (rr->RequireGoodbye && rr->resrec.RecordType == kDNSRecordTypeShared)
461                         debugf("Have announced shared record %##s (%s) at least once: should have sent a goodbye packet before updating",
462                                 rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
463
464                 rr->AnnounceCount  = InitialAnnounceCount;
465                 rr->RequireGoodbye = mDNSfalse;
466                 InitializeLastAPTime(m, rr);
467                 }
468         }
469
470 mDNSlocal void AcknowledgeRecord(mDNS *const m, AuthRecord *const rr)
471         {
472         if (rr->RecordCallback)
473                 {
474                 // CAUTION: MUST NOT do anything more with rr after calling rr->Callback(), because the client's callback function
475                 // is allowed to do anything, including starting/stopping queries, registering/deregistering records, etc.
476                 rr->Acknowledged = mDNStrue;
477                 mDNS_DropLockBeforeCallback();          // Allow client to legally make mDNS API calls from the callback
478                 rr->RecordCallback(m, rr, mStatus_NoError);
479                 mDNS_ReclaimLockAfterCallback();        // Decrement mDNS_reentrancy to block mDNS API calls again
480                 }
481         }
482
483 mDNSlocal void ActivateUnicastRegistration(mDNS *const m, AuthRecord *const rr)
484         {
485         rr->ProbeCount     = 0;
486         rr->AnnounceCount  = 0;
487         rr->ThisAPInterval = 5 * mDNSPlatformOneSecond;         // After doubling, first retry will happen after ten seconds
488         rr->LastAPTime     = m->timenow - rr->ThisAPInterval;
489         rr->state = regState_FetchingZoneData;
490         rr->uselease = mDNStrue;
491         }
492
493 // Two records qualify to be local duplicates if the RecordTypes are the same, or if one is Unique and the other Verified
494 #define RecordLDT(A,B) ((A)->resrec.RecordType == (B)->resrec.RecordType || \
495         ((A)->resrec.RecordType | (B)->resrec.RecordType) == (kDNSRecordTypeUnique | kDNSRecordTypeVerified))
496 #define RecordIsLocalDuplicate(A,B) \
497         ((A)->resrec.InterfaceID == (B)->resrec.InterfaceID && RecordLDT((A),(B)) && IdenticalResourceRecord(&(A)->resrec, &(B)->resrec))
498
499 // Exported so uDNS.c can call this
500 mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
501         {
502         domainname *target = GetRRDomainNameTarget(&rr->resrec);
503         AuthRecord *r;
504         AuthRecord **p = &m->ResourceRecords;
505         AuthRecord **d = &m->DuplicateRecords;
506
507         if ((mDNSs32)rr->resrec.rroriginalttl <= 0)
508                 { LogMsg("mDNS_Register_internal: TTL must be 1 - 0x7FFFFFFF %s", ARDisplayString(m, rr)); return(mStatus_BadParamErr); }
509
510         if (!rr->resrec.RecordType)
511                 { LogMsg("mDNS_Register_internal: RecordType must be non-zero %s", ARDisplayString(m, rr)); return(mStatus_BadParamErr); }
512
513         if (m->ShutdownTime)
514                 { LogMsg("mDNS_Register_internal: Shutting down, can't register %s", ARDisplayString(m, rr)); return(mStatus_ServiceNotRunning); }
515         
516         if (m->DivertMulticastAdvertisements && !AuthRecord_uDNS(rr))
517                 {
518                 mDNSInterfaceID previousID = rr->resrec.InterfaceID;
519                 if (rr->resrec.InterfaceID == mDNSInterface_Any) rr->resrec.InterfaceID = mDNSInterface_LocalOnly;
520                 if (rr->resrec.InterfaceID != mDNSInterface_LocalOnly)
521                         {
522                         NetworkInterfaceInfo *intf = FirstInterfaceForID(m, rr->resrec.InterfaceID);
523                         if (intf && !intf->Advertise) rr->resrec.InterfaceID = mDNSInterface_LocalOnly;
524                         }
525                 if (rr->resrec.InterfaceID != previousID)
526                         LogInfo("mDNS_Register_internal: Diverting record to local-only %s", ARDisplayString(m, rr));
527                 }
528
529         while (*p && *p != rr) p=&(*p)->next;
530         while (*d && *d != rr) d=&(*d)->next;
531         if (*d || *p)
532                 {
533                 LogMsg("Error! Tried to register AuthRecord %p %##s (%s) that's already in the list",
534                         rr, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
535                 return(mStatus_AlreadyRegistered);
536                 }
537
538         if (rr->DependentOn)
539                 {
540                 if (rr->resrec.RecordType == kDNSRecordTypeUnique)
541                         rr->resrec.RecordType =  kDNSRecordTypeVerified;
542                 else
543                         {
544                         LogMsg("mDNS_Register_internal: ERROR! %##s (%s): rr->DependentOn && RecordType != kDNSRecordTypeUnique",
545                                 rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
546                         return(mStatus_Invalid);
547                         }
548                 if (!(rr->DependentOn->resrec.RecordType & (kDNSRecordTypeUnique | kDNSRecordTypeVerified)))
549                         {
550                         LogMsg("mDNS_Register_internal: ERROR! %##s (%s): rr->DependentOn->RecordType bad type %X",
551                                 rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype), rr->DependentOn->resrec.RecordType);
552                         return(mStatus_Invalid);
553                         }
554                 }
555
556         // If this resource record is referencing a specific interface, make sure it exists
557         if (rr->resrec.InterfaceID && rr->resrec.InterfaceID != mDNSInterface_LocalOnly)
558                 {
559                 NetworkInterfaceInfo *intf = FirstInterfaceForID(m, rr->resrec.InterfaceID);
560                 if (!intf)
561                         {
562                         debugf("mDNS_Register_internal: Bogus InterfaceID %p in resource record", rr->resrec.InterfaceID);
563                         return(mStatus_BadReferenceErr);
564                         }
565                 }
566
567         rr->next = mDNSNULL;
568
569         // Field Group 1: The actual information pertaining to this resource record
570         // Set up by client prior to call
571
572         // Field Group 2: Persistent metadata for Authoritative Records
573 //      rr->Additional1       = set to mDNSNULL  in mDNS_SetupResourceRecord; may be overridden by client
574 //      rr->Additional2       = set to mDNSNULL  in mDNS_SetupResourceRecord; may be overridden by client
575 //      rr->DependentOn       = set to mDNSNULL  in mDNS_SetupResourceRecord; may be overridden by client
576 //      rr->RRSet             = set to mDNSNULL  in mDNS_SetupResourceRecord; may be overridden by client
577 //      rr->Callback          = already set      in mDNS_SetupResourceRecord
578 //      rr->Context           = already set      in mDNS_SetupResourceRecord
579 //      rr->RecordType        = already set      in mDNS_SetupResourceRecord
580 //      rr->HostTarget        = set to mDNSfalse in mDNS_SetupResourceRecord; may be overridden by client
581 //      rr->AllowRemoteQuery  = set to mDNSfalse in mDNS_SetupResourceRecord; may be overridden by client
582         // Make sure target is not uninitialized data, or we may crash writing debugging log messages
583         if (rr->AutoTarget && target) target->c[0] = 0;
584
585         // Field Group 3: Transient state for Authoritative Records
586         rr->Acknowledged      = mDNSfalse;
587         rr->ProbeCount        = DefaultProbeCountForRecordType(rr->resrec.RecordType);
588         rr->AnnounceCount     = InitialAnnounceCount;
589         rr->RequireGoodbye    = mDNSfalse;
590         rr->AnsweredLocalQ    = mDNSfalse;
591         rr->IncludeInProbe    = mDNSfalse;
592         rr->ImmedUnicast      = mDNSfalse;
593         rr->SendNSECNow       = mDNSNULL;
594         rr->ImmedAnswer       = mDNSNULL;
595         rr->ImmedAdditional   = mDNSNULL;
596         rr->SendRNow          = mDNSNULL;
597         rr->v4Requester       = zerov4Addr;
598         rr->v6Requester       = zerov6Addr;
599         rr->NextResponse      = mDNSNULL;
600         rr->NR_AnswerTo       = mDNSNULL;
601         rr->NR_AdditionalTo   = mDNSNULL;
602         if (!rr->AutoTarget) InitializeLastAPTime(m, rr);
603 //      rr->LastAPTime        = Set for us in InitializeLastAPTime()
604 //      rr->LastMCTime        = Set for us in InitializeLastAPTime()
605 //      rr->LastMCInterface   = Set for us in InitializeLastAPTime()
606         rr->NewRData          = mDNSNULL;
607         rr->newrdlength       = 0;
608         rr->UpdateCallback    = mDNSNULL;
609         rr->UpdateCredits     = kMaxUpdateCredits;
610         rr->NextUpdateCredit  = 0;
611         rr->UpdateBlocked     = 0;
612
613         // For records we're holding as proxy (except reverse-mapping PTR records) two announcements is sufficient
614         if (rr->WakeUp.HMAC.l[0] && !rr->AddressProxy.type) rr->AnnounceCount = 2;
615
616         // Field Group 4: Transient uDNS state for Authoritative Records
617         rr->state             = regState_Zero;
618         rr->uselease          = 0;
619         rr->expire            = 0;
620         rr->Private           = 0;
621         rr->updateid          = zeroID;
622         rr->zone              = rr->resrec.name;
623         rr->UpdateServer      = zeroAddr;
624         rr->UpdatePort        = zeroIPPort;
625         rr->nta               = mDNSNULL;
626         rr->tcp               = mDNSNULL;
627         rr->OrigRData         = 0;
628         rr->OrigRDLen         = 0;
629         rr->InFlightRData     = 0;
630         rr->InFlightRDLen     = 0;
631         rr->QueuedRData       = 0;
632         rr->QueuedRDLen       = 0;
633
634 //      rr->resrec.interface         = already set in mDNS_SetupResourceRecord
635 //      rr->resrec.name->c           = MUST be set by client
636 //      rr->resrec.rrtype            = already set in mDNS_SetupResourceRecord
637 //      rr->resrec.rrclass           = already set in mDNS_SetupResourceRecord
638 //      rr->resrec.rroriginalttl     = already set in mDNS_SetupResourceRecord
639 //      rr->resrec.rdata             = MUST be set by client, unless record type is CNAME or PTR and rr->HostTarget is set
640
641         if (rr->AutoTarget)
642                 SetTargetToHostName(m, rr);     // Also sets rdlength and rdestimate for us, and calls InitializeLastAPTime();
643         else
644                 {
645                 rr->resrec.rdlength   = GetRDLength(&rr->resrec, mDNSfalse);
646                 rr->resrec.rdestimate = GetRDLength(&rr->resrec, mDNStrue);
647                 }
648
649         if (!ValidateDomainName(rr->resrec.name))
650                 { LogMsg("Attempt to register record with invalid name: %s", ARDisplayString(m, rr)); return(mStatus_Invalid); }
651
652         // BIND named (name daemon) doesn't allow TXT records with zero-length rdata. This is strictly speaking correct,
653         // since RFC 1035 specifies a TXT record as "One or more <character-string>s", not "Zero or more <character-string>s".
654         // Since some legacy apps try to create zero-length TXT records, we'll silently correct it here.
655         if (rr->resrec.rrtype == kDNSType_TXT && rr->resrec.rdlength == 0) { rr->resrec.rdlength = 1; rr->resrec.rdata->u.txt.c[0] = 0; }
656
657         // Don't do this until *after* we've set rr->resrec.rdlength
658         if (!ValidateRData(rr->resrec.rrtype, rr->resrec.rdlength, rr->resrec.rdata))
659                 { LogMsg("Attempt to register record with invalid rdata: %s", ARDisplayString(m, rr)); return(mStatus_Invalid); }
660
661         rr->resrec.namehash   = DomainNameHashValue(rr->resrec.name);
662         rr->resrec.rdatahash  = target ? DomainNameHashValue(target) : RDataHashValue(&rr->resrec);
663         
664         if (rr->resrec.InterfaceID == mDNSInterface_LocalOnly)
665                 {
666                 // If this is supposed to be unique, make sure we don't have any name conflicts
667                 if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
668                         {
669                         const AuthRecord *s1 = rr->RRSet ? rr->RRSet : rr;
670                         for (r = m->ResourceRecords; r; r=r->next)
671                                 {
672                                 const AuthRecord *s2 = r->RRSet ? r->RRSet : r;
673                                 if (s1 != s2 && SameResourceRecordSignature(r, rr) && !IdenticalSameNameRecord(&r->resrec, &rr->resrec))
674                                         break;
675                                 }
676                         if (r)  // If we found a conflict, set RecordType = kDNSRecordTypeDeregistering so we'll deliver the callback
677                                 {
678                                 debugf("Name conflict %p %##s (%s)", rr, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
679                                 rr->resrec.RecordType    = kDNSRecordTypeDeregistering;
680                                 rr->resrec.rroriginalttl = 0;
681                                 rr->ImmedAnswer          = mDNSInterfaceMark;
682                                 m->LocalRemoveEvents     = mDNStrue;
683                                 m->NextScheduledResponse = m->timenow;
684                                 }
685                         }
686                 }
687
688         // Now that we've finished building our new record, make sure it's not identical to one we already have
689         for (r = m->ResourceRecords; r; r=r->next) if (RecordIsLocalDuplicate(r, rr)) break;
690         
691         if (r)
692                 {
693                 debugf("Adding to duplicate list %p %s", rr, ARDisplayString(m,rr));
694                 *d = rr;
695                 // If the previous copy of this record is already verified unique,
696                 // then indicate that we should move this record promptly to kDNSRecordTypeUnique state.
697                 // Setting ProbeCount to zero will cause SendQueries() to advance this record to
698                 // kDNSRecordTypeVerified state and call the client callback at the next appropriate time.
699                 if (rr->resrec.RecordType == kDNSRecordTypeUnique && r->resrec.RecordType == kDNSRecordTypeVerified)
700                         rr->ProbeCount = 0;
701                 }
702         else
703                 {
704                 debugf("Adding to active record list %p %s", rr, ARDisplayString(m,rr));
705                 if (!m->NewLocalRecords) m->NewLocalRecords = rr;
706                 *p = rr;
707                 }
708
709         if (!AuthRecord_uDNS(rr))
710                 {
711                 // For records that are not going to probe, acknowledge them right away
712                 if (rr->resrec.RecordType != kDNSRecordTypeUnique && rr->resrec.RecordType != kDNSRecordTypeDeregistering)
713                         AcknowledgeRecord(m, rr);
714                 }
715 #ifndef UNICAST_DISABLED
716         else
717                 {
718                 if (rr->resrec.RecordType == kDNSRecordTypeUnique) rr->resrec.RecordType = kDNSRecordTypeVerified;
719                 ActivateUnicastRegistration(m, rr);
720                 }
721 #endif
722         
723         return(mStatus_NoError);
724         }
725
726 mDNSlocal void RecordProbeFailure(mDNS *const m, const AuthRecord *const rr)
727         {
728         m->ProbeFailTime = m->timenow;
729         m->NumFailedProbes++;
730         // If we've had fifteen or more probe failures, rate-limit to one every five seconds.
731         // If a bunch of hosts have all been configured with the same name, then they'll all
732         // conflict and run through the same series of names: name-2, name-3, name-4, etc.,
733         // up to name-10. After that they'll start adding random increments in the range 1-100,
734         // so they're more likely to branch out in the available namespace and settle on a set of
735         // unique names quickly. If after five more tries the host is still conflicting, then we
736         // may have a serious problem, so we start rate-limiting so we don't melt down the network.
737         if (m->NumFailedProbes >= 15)
738                 {
739                 m->SuppressProbes = NonZeroTime(m->timenow + mDNSPlatformOneSecond * 5);
740                 LogMsg("Excessive name conflicts (%lu) for %##s (%s); rate limiting in effect",
741                         m->NumFailedProbes, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
742                 }
743         }
744
745 mDNSlocal void CompleteRDataUpdate(mDNS *const m, AuthRecord *const rr)
746         {
747         RData *OldRData = rr->resrec.rdata;
748         SetNewRData(&rr->resrec, rr->NewRData, rr->newrdlength);        // Update our rdata
749         rr->NewRData = mDNSNULL;                                                                        // Clear the NewRData pointer ...
750         if (rr->UpdateCallback)
751                 rr->UpdateCallback(m, rr, OldRData);                                    // ... and let the client know
752         }
753
754 // Note: mDNS_Deregister_internal can call a user callback, which may change the record list and/or question list.
755 // Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
756 // Exported so uDNS.c can call this
757 mDNSexport mStatus mDNS_Deregister_internal(mDNS *const m, AuthRecord *const rr, mDNS_Dereg_type drt)
758         {
759         AuthRecord *r2;
760         mDNSu8 RecordType = rr->resrec.RecordType;
761         AuthRecord **p = &m->ResourceRecords;   // Find this record in our list of active records
762
763         while (*p && *p != rr) p=&(*p)->next;
764
765         if (*p)
766                 {
767                 // We found our record on the main list. See if there are any duplicates that need special handling.
768                 if (drt == mDNS_Dereg_conflict)         // If this was a conflict, see that all duplicates get the same treatment
769                         {
770                         // Scan for duplicates of rr, and mark them for deregistration at the end of this routine, after we've finished
771                         // deregistering rr. We need to do this scan *before* we give the client the chance to free and reuse the rr memory.
772                         for (r2 = m->DuplicateRecords; r2; r2=r2->next) if (RecordIsLocalDuplicate(r2, rr)) r2->ProbeCount = 0xFF;
773                         }
774                 else
775                         {
776                         // Before we delete the record (and potentially send a goodbye packet)
777                         // first see if we have a record on the duplicate list ready to take over from it.
778                         AuthRecord **d = &m->DuplicateRecords;
779                         while (*d && !RecordIsLocalDuplicate(*d, rr)) d=&(*d)->next;
780                         if (*d)
781                                 {
782                                 AuthRecord *dup = *d;
783                                 debugf("Duplicate record %p taking over from %p %##s (%s)",
784                                         dup, rr, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
785                                 *d        = dup->next;          // Cut replacement record from DuplicateRecords list
786                                 dup->next = rr->next;           // And then...
787                                 rr->next  = dup;                        // ... splice it in right after the record we're about to delete
788                                 dup->resrec.RecordType        = rr->resrec.RecordType;
789                                 dup->ProbeCount      = rr->ProbeCount;
790                                 dup->AnnounceCount   = rr->AnnounceCount;
791                                 dup->RequireGoodbye  = rr->RequireGoodbye;
792                                 dup->AnsweredLocalQ  = rr->AnsweredLocalQ;
793                                 dup->ImmedAnswer     = rr->ImmedAnswer;
794                                 dup->ImmedUnicast    = rr->ImmedUnicast;
795                                 dup->ImmedAdditional = rr->ImmedAdditional;
796                                 dup->v4Requester     = rr->v4Requester;
797                                 dup->v6Requester     = rr->v6Requester;
798                                 dup->ThisAPInterval  = rr->ThisAPInterval;
799                                 dup->LastAPTime      = rr->LastAPTime;
800                                 dup->LastMCTime      = rr->LastMCTime;
801                                 dup->LastMCInterface = rr->LastMCInterface;
802                                 dup->UpdateServer    = rr->UpdateServer;
803                                 dup->UpdatePort      = rr->UpdatePort;
804                                 dup->Private         = rr->Private;
805                                 dup->state           = rr->state;
806                                 rr->RequireGoodbye = mDNSfalse;
807                                 rr->AnsweredLocalQ = mDNSfalse;
808                                 }
809                         }
810                 }
811         else
812                 {
813                 // We didn't find our record on the main list; try the DuplicateRecords list instead.
814                 p = &m->DuplicateRecords;
815                 while (*p && *p != rr) p=&(*p)->next;
816                 // If we found our record on the duplicate list, then make sure we don't send a goodbye for it
817                 if (*p) rr->RequireGoodbye = mDNSfalse;
818                 if (*p) debugf("DNS_Deregister_internal: Deleting DuplicateRecord %p %##s (%s)",
819                         rr, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
820                 }
821
822         if (!*p)
823                 {
824                 // No need to log an error message if we already know this is a potentially repeated deregistration
825                 if (drt != mDNS_Dereg_repeat)
826                         LogMsg("mDNS_Deregister_internal: Record %p not found in list %s", rr, ARDisplayString(m,rr));
827                 return(mStatus_BadReferenceErr);
828                 }
829
830         // If this is a shared record and we've announced it at least once,
831         // we need to retract that announcement before we delete the record
832
833         // If this is a record (including mDNSInterface_LocalOnly records) for which we've given local-only answers then
834         // it's tempting to just do "AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse)" here, but that would not not be safe.
835         // The AnswerAllLocalQuestionsWithLocalAuthRecord routine walks the question list invoking client callbacks, using the "m->CurrentQuestion"
836         // mechanism to cope with the client callback modifying the question list while that's happening.
837         // However, mDNS_Deregister could have been called from a client callback (e.g. from the domain enumeration callback FoundDomain)
838         // which means that the "m->CurrentQuestion" mechanism is already in use to protect that list, so we can't use it twice.
839         // More generally, if we invoke callbacks from within a client callback, then those callbacks could deregister other
840         // records, thereby invoking yet more callbacks, without limit.
841         // The solution is to defer delivering the "Remove" events until mDNS_Execute time, just like we do for sending
842         // actual goodbye packets.
843         
844 #ifndef UNICAST_DISABLED
845         if (AuthRecord_uDNS(rr) && rr->RequireGoodbye)
846                 {
847                 if (rr->tcp) { DisposeTCPConn(rr->tcp); rr->tcp = mDNSNULL; }
848                 rr->resrec.RecordType    = kDNSRecordTypeDeregistering;
849                 m->LocalRemoveEvents     = mDNStrue;
850                 uDNS_DeregisterRecord(m, rr);
851                 // At this point unconditionally we bail out
852                 // Either uDNS_DeregisterRecord will have completed synchronously, and called CompleteDeregistration,
853                 // which calls us back here with RequireGoodbye set to false, or it will have initiated the deregistration
854                 // process and will complete asynchronously. Either way we don't need to do anything more here.
855                 return(mStatus_NoError);
856                 }
857 #endif // UNICAST_DISABLED
858
859         if      (RecordType == kDNSRecordTypeUnregistered)
860                 LogMsg("mDNS_Deregister_internal: %s already marked kDNSRecordTypeUnregistered", ARDisplayString(m, rr));
861         else if (RecordType == kDNSRecordTypeDeregistering)
862                 LogMsg("mDNS_Deregister_internal: %s already marked kDNSRecordTypeDeregistering", ARDisplayString(m, rr));
863
864         // <rdar://problem/7457925> Local-only questions don't get remove events for unique records
865         // We may want to consider changing this code so that we generate local-only question "rmv"
866         // events (and maybe goodbye packets too) for unique records as well as for shared records
867         if (rr->WakeUp.HMAC.l[0] ||
868                 (RecordType == kDNSRecordTypeShared && (rr->RequireGoodbye || rr->AnsweredLocalQ)))
869                 {
870                 verbosedebugf("mDNS_Deregister_internal: Starting deregistration for %s", ARDisplayString(m, rr));
871                 rr->resrec.RecordType    = kDNSRecordTypeDeregistering;
872                 rr->resrec.rroriginalttl = 0;
873                 // For goodbye packets we set the count to 3, and for wakeups we set it to 18
874                 // (which will be up to 15 wakeup attempts over the course of 30 seconds,
875                 // and then if the machine fails to wake, 3 goodbye packets).
876                 rr->AnnounceCount        = rr->WakeUp.HMAC.l[0] ? 18: 3;
877                 rr->ThisAPInterval       = mDNSPlatformOneSecond * 2;
878                 rr->LastAPTime           = m->timenow - rr->ThisAPInterval;
879                 m->LocalRemoveEvents     = mDNStrue;
880                 if (m->NextScheduledResponse - (m->timenow + mDNSPlatformOneSecond/10) >= 0)
881                         m->NextScheduledResponse = (m->timenow + mDNSPlatformOneSecond/10);
882                 }
883         else
884                 {
885                 *p = rr->next;                                  // Cut this record from the list
886                 // If someone is about to look at this, bump the pointer forward
887                 if (m->CurrentRecord   == rr) m->CurrentRecord   = rr->next;
888                 if (m->NewLocalRecords == rr) m->NewLocalRecords = rr->next;
889                 rr->next = mDNSNULL;
890
891                 // Should we generate local remove events here?
892                 // i.e. something like:
893                 // if (rr->AnsweredLocalQ) { AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse); rr->AnsweredLocalQ = mDNSfalse; }
894
895                 verbosedebugf("mDNS_Deregister_internal: Deleting record for %s", ARDisplayString(m, rr));
896                 rr->resrec.RecordType = kDNSRecordTypeUnregistered;
897
898                 if ((drt == mDNS_Dereg_conflict || drt == mDNS_Dereg_repeat) && RecordType == kDNSRecordTypeShared)
899                         debugf("mDNS_Deregister_internal: Cannot have a conflict on a shared record! %##s (%s)",
900                                 rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
901
902                 // If we have an update queued up which never executed, give the client a chance to free that memory
903                 if (rr->NewRData) CompleteRDataUpdate(m, rr);   // Update our rdata, clear the NewRData pointer, and return memory to the client
904
905                 if (rr->nta) { CancelGetZoneData(m, rr->nta); rr->nta = mDNSNULL; }
906                 if (rr->tcp) { DisposeTCPConn(rr->tcp);       rr->tcp = mDNSNULL; }
907
908                 // CAUTION: MUST NOT do anything more with rr after calling rr->Callback(), because the client's callback function
909                 // is allowed to do anything, including starting/stopping queries, registering/deregistering records, etc.
910                 // In this case the likely client action to the mStatus_MemFree message is to free the memory,
911                 // so any attempt to touch rr after this is likely to lead to a crash.
912                 if (drt != mDNS_Dereg_conflict)
913                         {
914                         mDNS_DropLockBeforeCallback();          // Allow client to legally make mDNS API calls from the callback
915                         if (rr->RecordCallback)
916                                 rr->RecordCallback(m, rr, mStatus_MemFree);                     // MUST NOT touch rr after this
917                         mDNS_ReclaimLockAfterCallback();        // Decrement mDNS_reentrancy to block mDNS API calls again
918                         }
919                 else
920                         {
921                         RecordProbeFailure(m, rr);
922                         mDNS_DropLockBeforeCallback();          // Allow client to legally make mDNS API calls from the callback
923                         if (rr->RecordCallback)
924                                 rr->RecordCallback(m, rr, mStatus_NameConflict);        // MUST NOT touch rr after this
925                         mDNS_ReclaimLockAfterCallback();        // Decrement mDNS_reentrancy to block mDNS API calls again
926                         // Now that we've finished deregistering rr, check our DuplicateRecords list for any that we marked previously.
927                         // Note that with all the client callbacks going on, by the time we get here all the
928                         // records we marked may have been explicitly deregistered by the client anyway.
929                         r2 = m->DuplicateRecords;
930                         while (r2)
931                                 {
932                                 if (r2->ProbeCount != 0xFF) r2 = r2->next;
933                                 else { mDNS_Deregister_internal(m, r2, mDNS_Dereg_conflict); r2 = m->DuplicateRecords; }
934                                 }
935                         }
936                 }
937         return(mStatus_NoError);
938         }
939
940 // ***************************************************************************
941 #if COMPILER_LIKES_PRAGMA_MARK
942 #pragma mark -
943 #pragma mark - Packet Sending Functions
944 #endif
945
946 mDNSlocal void AddRecordToResponseList(AuthRecord ***nrpp, AuthRecord *rr, AuthRecord *add)
947         {
948         if (rr->NextResponse == mDNSNULL && *nrpp != &rr->NextResponse)
949                 {
950                 **nrpp = rr;
951                 // NR_AdditionalTo must point to a record with NR_AnswerTo set (and not NR_AdditionalTo)
952                 // If 'add' does not meet this requirement, then follow its NR_AdditionalTo pointer to a record that does
953                 // The referenced record will definitely be acceptable (by recursive application of this rule)
954                 if (add && add->NR_AdditionalTo) add = add->NR_AdditionalTo;
955                 rr->NR_AdditionalTo = add;
956                 *nrpp = &rr->NextResponse;
957                 }
958         debugf("AddRecordToResponseList: %##s (%s) already in list", rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
959         }
960
961 mDNSlocal void AddAdditionalsToResponseList(mDNS *const m, AuthRecord *ResponseRecords, AuthRecord ***nrpp, const mDNSInterfaceID InterfaceID)
962         {
963         AuthRecord  *rr, *rr2;
964         for (rr=ResponseRecords; rr; rr=rr->NextResponse)                       // For each record we plan to put
965                 {
966                 // (Note: This is an "if", not a "while". If we add a record, we'll find it again
967                 // later in the "for" loop, and we will follow further "additional" links then.)
968                 if (rr->Additional1 && ResourceRecordIsValidInterfaceAnswer(rr->Additional1, InterfaceID))
969                         AddRecordToResponseList(nrpp, rr->Additional1, rr);
970
971                 if (rr->Additional2 && ResourceRecordIsValidInterfaceAnswer(rr->Additional2, InterfaceID))
972                         AddRecordToResponseList(nrpp, rr->Additional2, rr);
973
974                 // For SRV records, automatically add the Address record(s) for the target host
975                 if (rr->resrec.rrtype == kDNSType_SRV)
976                         {
977                         for (rr2=m->ResourceRecords; rr2; rr2=rr2->next)                                        // Scan list of resource records
978                                 if (RRTypeIsAddressType(rr2->resrec.rrtype) &&                                  // For all address records (A/AAAA) ...
979                                         ResourceRecordIsValidInterfaceAnswer(rr2, InterfaceID) &&       // ... which are valid for answer ...
980                                         rr->resrec.rdatahash == rr2->resrec.namehash &&                 // ... whose name is the name of the SRV target
981                                         SameDomainName(&rr->resrec.rdata->u.srv.target, rr2->resrec.name))
982                                         AddRecordToResponseList(nrpp, rr2, rr);
983                         }
984                 else if (RRTypeIsAddressType(rr->resrec.rrtype))        // For A or AAAA, put counterpart as additional
985                         {
986                         for (rr2=m->ResourceRecords; rr2; rr2=rr2->next)                                        // Scan list of resource records
987                                 if (RRTypeIsAddressType(rr2->resrec.rrtype) &&                                  // For all address records (A/AAAA) ...
988                                         ResourceRecordIsValidInterfaceAnswer(rr2, InterfaceID) &&       // ... which are valid for answer ...
989                                         rr->resrec.namehash == rr2->resrec.namehash &&                          // ... and have the same name
990                                         SameDomainName(rr->resrec.name, rr2->resrec.name))
991                                         AddRecordToResponseList(nrpp, rr2, rr);
992                         }
993                 else if (rr->resrec.rrtype == kDNSType_PTR)                     // For service PTR, see if we want to add DeviceInfo record
994                         {
995                         if (ResourceRecordIsValidInterfaceAnswer(&m->DeviceInfo, InterfaceID) &&
996                                 SameDomainLabel(rr->resrec.rdata->u.name.c, m->DeviceInfo.resrec.name->c))
997                                 AddRecordToResponseList(nrpp, &m->DeviceInfo, rr);
998                         }
999                 }
1000         }
1001
1002 mDNSlocal void SendDelayedUnicastResponse(mDNS *const m, const mDNSAddr *const dest, const mDNSInterfaceID InterfaceID)
1003         {
1004         AuthRecord *rr;
1005         AuthRecord  *ResponseRecords = mDNSNULL;
1006         AuthRecord **nrp             = &ResponseRecords;
1007
1008         // Make a list of all our records that need to be unicast to this destination
1009         for (rr = m->ResourceRecords; rr; rr=rr->next)
1010                 {
1011                 // If we find we can no longer unicast this answer, clear ImmedUnicast
1012                 if (rr->ImmedAnswer == mDNSInterfaceMark               ||
1013                         mDNSSameIPv4Address(rr->v4Requester, onesIPv4Addr) ||
1014                         mDNSSameIPv6Address(rr->v6Requester, onesIPv6Addr)  )
1015                         rr->ImmedUnicast = mDNSfalse;
1016
1017                 if (rr->ImmedUnicast && rr->ImmedAnswer == InterfaceID)
1018                         if ((dest->type == mDNSAddrType_IPv4 && mDNSSameIPv4Address(rr->v4Requester, dest->ip.v4)) ||
1019                                 (dest->type == mDNSAddrType_IPv6 && mDNSSameIPv6Address(rr->v6Requester, dest->ip.v6)))
1020                                 {
1021                                 rr->ImmedAnswer  = mDNSNULL;                            // Clear the state fields
1022                                 rr->ImmedUnicast = mDNSfalse;
1023                                 rr->v4Requester  = zerov4Addr;
1024                                 rr->v6Requester  = zerov6Addr;
1025                                 if (rr->NextResponse == mDNSNULL && nrp != &rr->NextResponse)   // rr->NR_AnswerTo
1026                                         { rr->NR_AnswerTo = (mDNSu8*)~0; *nrp = rr; nrp = &rr->NextResponse; }
1027                                 }
1028                 }
1029
1030         AddAdditionalsToResponseList(m, ResponseRecords, &nrp, InterfaceID);
1031
1032         while (ResponseRecords)
1033                 {
1034                 mDNSu8 *responseptr = m->omsg.data;
1035                 mDNSu8 *newptr;
1036                 InitializeDNSMessage(&m->omsg.h, zeroID, ResponseFlags);
1037                 
1038                 // Put answers in the packet
1039                 while (ResponseRecords && ResponseRecords->NR_AnswerTo)
1040                         {
1041                         rr = ResponseRecords;
1042                         if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
1043                                 rr->resrec.rrclass |= kDNSClass_UniqueRRSet;            // Temporarily set the cache flush bit so PutResourceRecord will set it
1044                         newptr = PutResourceRecord(&m->omsg, responseptr, &m->omsg.h.numAnswers, &rr->resrec);
1045                         rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet;                   // Make sure to clear cache flush bit back to normal state
1046                         if (!newptr && m->omsg.h.numAnswers) break;     // If packet full, send it now
1047                         if (newptr) responseptr = newptr;
1048                         ResponseRecords = rr->NextResponse;
1049                         rr->NextResponse    = mDNSNULL;
1050                         rr->NR_AnswerTo     = mDNSNULL;
1051                         rr->NR_AdditionalTo = mDNSNULL;
1052                         rr->RequireGoodbye  = mDNStrue;
1053                         }
1054                 
1055                 // Add additionals, if there's space
1056                 while (ResponseRecords && !ResponseRecords->NR_AnswerTo)
1057                         {
1058                         rr = ResponseRecords;
1059                         if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
1060                                 rr->resrec.rrclass |= kDNSClass_UniqueRRSet;            // Temporarily set the cache flush bit so PutResourceRecord will set it
1061                         newptr = PutResourceRecord(&m->omsg, responseptr, &m->omsg.h.numAdditionals, &rr->resrec);
1062                         rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet;                   // Make sure to clear cache flush bit back to normal state
1063                         
1064                         if (newptr) responseptr = newptr;
1065                         if (newptr && m->omsg.h.numAnswers) rr->RequireGoodbye = mDNStrue;
1066                         else if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask) rr->ImmedAnswer = mDNSInterfaceMark;
1067                         ResponseRecords = rr->NextResponse;
1068                         rr->NextResponse    = mDNSNULL;
1069                         rr->NR_AnswerTo     = mDNSNULL;
1070                         rr->NR_AdditionalTo = mDNSNULL;
1071                         }
1072
1073                 if (m->omsg.h.numAnswers)
1074                         mDNSSendDNSMessage(m, &m->omsg, responseptr, mDNSInterface_Any, mDNSNULL, dest, MulticastDNSPort, mDNSNULL, mDNSNULL);
1075                 }
1076         }
1077
1078 mDNSexport void CompleteDeregistration(mDNS *const m, AuthRecord *rr)
1079         {
1080         // Clearing rr->RequireGoodbye signals mDNS_Deregister_internal() that
1081         // it should go ahead and immediately dispose of this registration
1082         rr->resrec.RecordType = kDNSRecordTypeShared;
1083         rr->RequireGoodbye    = mDNSfalse;
1084         if (rr->AnsweredLocalQ) { AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse); rr->AnsweredLocalQ = mDNSfalse; }
1085         mDNS_Deregister_internal(m, rr, mDNS_Dereg_normal);             // Don't touch rr after this
1086         }
1087
1088 // Note: DiscardDeregistrations calls mDNS_Deregister_internal which can call a user callback, which may change
1089 // the record list and/or question list.
1090 // Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
1091 mDNSlocal void DiscardDeregistrations(mDNS *const m)
1092         {
1093         if (m->CurrentRecord)
1094                 LogMsg("DiscardDeregistrations ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
1095         m->CurrentRecord = m->ResourceRecords;
1096         
1097         while (m->CurrentRecord)
1098                 {
1099                 AuthRecord *rr = m->CurrentRecord;
1100                 if (rr->resrec.RecordType == kDNSRecordTypeDeregistering)
1101                         CompleteDeregistration(m, rr);          // Don't touch rr after this
1102                 else
1103                         m->CurrentRecord = rr->next;
1104                 }
1105         }
1106
1107 mDNSlocal mStatus GetLabelDecimalValue(const mDNSu8 *const src, mDNSu8 *dst)
1108         {
1109         int i, val = 0;
1110         if (src[0] < 1 || src[0] > 3) return(mStatus_Invalid);
1111         for (i=1; i<=src[0]; i++)
1112                 {
1113                 if (src[i] < '0' || src[i] > '9') return(mStatus_Invalid);
1114                 val = val * 10 + src[i] - '0';
1115                 }
1116         if (val > 255) return(mStatus_Invalid);
1117         *dst = (mDNSu8)val;
1118         return(mStatus_NoError);
1119         }
1120
1121 mDNSlocal mStatus GetIPv4FromName(mDNSAddr *const a, const domainname *const name)
1122         {
1123         int skip = CountLabels(name) - 6;
1124         if (skip < 0) { LogMsg("GetIPFromName: Need six labels in IPv4 reverse mapping name %##s", name); return mStatus_Invalid; }
1125         if (GetLabelDecimalValue(SkipLeadingLabels(name, skip+3)->c, &a->ip.v4.b[0]) ||
1126                 GetLabelDecimalValue(SkipLeadingLabels(name, skip+2)->c, &a->ip.v4.b[1]) ||
1127                 GetLabelDecimalValue(SkipLeadingLabels(name, skip+1)->c, &a->ip.v4.b[2]) ||
1128                 GetLabelDecimalValue(SkipLeadingLabels(name, skip+0)->c, &a->ip.v4.b[3])) return mStatus_Invalid;
1129         a->type = mDNSAddrType_IPv4;
1130         return(mStatus_NoError);
1131         }
1132
1133 #define HexVal(X) ( ((X) >= '0' && (X) <= '9') ? ((X) - '0'     ) :   \
1134                                         ((X) >= 'A' && (X) <= 'F') ? ((X) - 'A' + 10) :   \
1135                                         ((X) >= 'a' && (X) <= 'f') ? ((X) - 'a' + 10) : -1)
1136
1137 mDNSlocal mStatus GetIPv6FromName(mDNSAddr *const a, const domainname *const name)
1138         {
1139         int i, h, l;
1140         const domainname *n;
1141
1142         int skip = CountLabels(name) - 34;
1143         if (skip < 0) { LogMsg("GetIPFromName: Need 34 labels in IPv6 reverse mapping name %##s", name); return mStatus_Invalid; }
1144
1145         n = SkipLeadingLabels(name, skip);
1146         for (i=0; i<16; i++)
1147                 {
1148                 if (n->c[0] != 1) return mStatus_Invalid;
1149                 l = HexVal(n->c[1]);
1150                 n = (const domainname *)(n->c + 2);
1151
1152                 if (n->c[0] != 1) return mStatus_Invalid;
1153                 h = HexVal(n->c[1]);
1154                 n = (const domainname *)(n->c + 2);
1155
1156                 if (l<0 || h<0) return mStatus_Invalid;
1157                 a->ip.v6.b[15-i] = (mDNSu8)((h << 4) | l);
1158                 }
1159
1160         a->type = mDNSAddrType_IPv6;
1161         return(mStatus_NoError);
1162         }
1163
1164 mDNSlocal mDNSs32 ReverseMapDomainType(const domainname *const name)
1165         {
1166         int skip = CountLabels(name) - 2;
1167         if (skip >= 0)
1168                 {
1169                 const domainname *suffix = SkipLeadingLabels(name, skip);
1170                 if (SameDomainName(suffix, (const domainname*)"\x7" "in-addr" "\x4" "arpa")) return mDNSAddrType_IPv4;
1171                 if (SameDomainName(suffix, (const domainname*)"\x3" "ip6"     "\x4" "arpa")) return mDNSAddrType_IPv6;
1172                 }
1173         return(mDNSAddrType_None);
1174         }
1175
1176 mDNSlocal void SendARP(mDNS *const m, const mDNSu8 op, const AuthRecord *const rr,
1177         const mDNSv4Addr *const spa, const mDNSEthAddr *const tha, const mDNSv4Addr *const tpa, const mDNSEthAddr *const dst)
1178         {
1179         int i;
1180         mDNSu8 *ptr = m->omsg.data;
1181         NetworkInterfaceInfo *intf = FirstInterfaceForID(m, rr->resrec.InterfaceID);
1182         if (!intf) { LogMsg("SendARP: No interface with InterfaceID %p found %s", rr->resrec.InterfaceID, ARDisplayString(m,rr)); return; }
1183
1184         // 0x00 Destination address
1185         for (i=0; i<6; i++) *ptr++ = dst->b[i];
1186
1187         // 0x06 Source address (Note: Unless we set the BIOCSHDRCMPLT option, BPF will fill in real interface address)
1188         for (i=0; i<6; i++) *ptr++ = intf->MAC.b[0];
1189
1190         // 0x0C ARP Ethertype (0x0806)
1191         *ptr++ = 0x08; *ptr++ = 0x06;
1192
1193         // 0x0E ARP header
1194         *ptr++ = 0x00; *ptr++ = 0x01;   // Hardware address space; Ethernet = 1
1195         *ptr++ = 0x08; *ptr++ = 0x00;   // Protocol address space; IP = 0x0800
1196         *ptr++ = 6;                                             // Hardware address length
1197         *ptr++ = 4;                                             // Protocol address length
1198         *ptr++ = 0x00; *ptr++ = op;             // opcode; Request = 1, Response = 2
1199
1200         // 0x16 Sender hardware address (our MAC address)
1201         for (i=0; i<6; i++) *ptr++ = intf->MAC.b[i];
1202
1203         // 0x1C Sender protocol address
1204         for (i=0; i<4; i++) *ptr++ = spa->b[i];
1205
1206         // 0x20 Target hardware address
1207         for (i=0; i<6; i++) *ptr++ = tha->b[i];
1208
1209         // 0x26 Target protocol address
1210         for (i=0; i<4; i++) *ptr++ = tpa->b[i];
1211
1212         // 0x2A Total ARP Packet length 42 bytes
1213         mDNSPlatformSendRawPacket(m->omsg.data, ptr, rr->resrec.InterfaceID);
1214         }
1215
1216 mDNSlocal mDNSu16 CheckSum(const void *const data, mDNSs32 length, mDNSu32 sum)
1217         {
1218         const mDNSu16 *ptr = data;
1219         while (length > 0) { length -= 2; sum += *ptr++; }
1220         sum = (sum & 0xFFFF) + (sum >> 16);
1221         sum = (sum & 0xFFFF) + (sum >> 16);
1222         return(sum != 0xFFFF ? sum : 0);
1223         }
1224
1225 mDNSlocal mDNSu16 IPv6CheckSum(const mDNSv6Addr *const src, const mDNSv6Addr *const dst, const mDNSu8 protocol, const void *const data, const mDNSu32 length)
1226         {
1227         IPv6PseudoHeader ph;
1228         ph.src = *src;
1229         ph.dst = *dst;
1230         ph.len.b[0] = length >> 24;
1231         ph.len.b[1] = length >> 16;
1232         ph.len.b[2] = length >> 8;
1233         ph.len.b[3] = length;
1234         ph.pro.b[0] = 0;
1235         ph.pro.b[1] = 0;
1236         ph.pro.b[2] = 0;
1237         ph.pro.b[3] = protocol;
1238         return CheckSum(&ph, sizeof(ph), CheckSum(data, length, 0));
1239         }
1240
1241 mDNSlocal void SendNDP(mDNS *const m, const mDNSu8 op, const mDNSu8 flags, const AuthRecord *const rr,
1242         const mDNSv6Addr *const spa, const mDNSEthAddr *const tha, const mDNSv6Addr *const tpa, const mDNSEthAddr *const dst)
1243         {
1244         int i;
1245         mDNSOpaque16 checksum;
1246         mDNSu8 *ptr = m->omsg.data;
1247         // Some recipient hosts seem to ignore Neighbor Solicitations if the IPv6-layer destination address is not the
1248         // appropriate IPv6 solicited node multicast address, so we use that IPv6-layer destination address, even though
1249         // at the Ethernet-layer we unicast the packet to the intended target, to avoid wasting network bandwidth.
1250         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] } };
1251         const mDNSv6Addr *const v6dst = (op == 0x87) ? &mc : tpa;
1252         NetworkInterfaceInfo *intf = FirstInterfaceForID(m, rr->resrec.InterfaceID);
1253         if (!intf) { LogMsg("SendNDP: No interface with InterfaceID %p found %s", rr->resrec.InterfaceID, ARDisplayString(m,rr)); return; }
1254
1255         // 0x00 Destination address
1256         for (i=0; i<6; i++) *ptr++ = dst->b[i];
1257         // Right now we only send Neighbor Solicitations to verify whether the host we're proxying for has gone to sleep yet.
1258         // Since we know who we're looking for, we send it via Ethernet-layer unicast, rather than bothering every host on the
1259         // link with a pointless link-layer multicast.
1260         // Should we want to send traditional Neighbor Solicitations in the future, where we really don't know in advance what
1261         // Ethernet-layer address we're looking for, we'll need to send to the appropriate Ethernet-layer multicast address:
1262         // *ptr++ = 0x33;
1263         // *ptr++ = 0x33;
1264         // *ptr++ = 0xFF;
1265         // *ptr++ = tpa->b[0xD];
1266         // *ptr++ = tpa->b[0xE];
1267         // *ptr++ = tpa->b[0xF];
1268
1269         // 0x06 Source address (Note: Unless we set the BIOCSHDRCMPLT option, BPF will fill in real interface address)
1270         for (i=0; i<6; i++) *ptr++ = (tha ? *tha : intf->MAC).b[i];
1271
1272         // 0x0C IPv6 Ethertype (0x86DD)
1273         *ptr++ = 0x86; *ptr++ = 0xDD;
1274
1275         // 0x0E IPv6 header
1276         *ptr++ = 0x60; *ptr++ = 0x00; *ptr++ = 0x00; *ptr++ = 0x00;             // Version, Traffic Class, Flow Label
1277         *ptr++ = 0x00; *ptr++ = 0x20;                                                                   // Length
1278         *ptr++ = 0x3A;                                                                                                  // Protocol == ICMPv6
1279         *ptr++ = 0xFF;                                                                                                  // Hop Limit
1280
1281         // 0x16 Sender IPv6 address
1282         for (i=0; i<16; i++) *ptr++ = spa->b[i];
1283
1284         // 0x26 Destination IPv6 address
1285         for (i=0; i<16; i++) *ptr++ = v6dst->b[i];
1286
1287         // 0x36 NDP header
1288         *ptr++ = op;                                    // 0x87 == Neighbor Solicitation, 0x88 == Neighbor Advertisement
1289         *ptr++ = 0x00;                                  // Code
1290         *ptr++ = 0x00; *ptr++ = 0x00;   // Checksum placeholder (0x38, 0x39)
1291         *ptr++ = flags;
1292         *ptr++ = 0x00; *ptr++ = 0x00; *ptr++ = 0x00;
1293
1294         // In Neighbor Solicitations, the NDP "target" is the desired address
1295         // In Neighbor Advertisements, the NDP "target" is the sender
1296         if (op == 0x87)
1297                 {
1298                 // 0x3E NDP target.
1299                 for (i=0; i<16; i++) *ptr++ = tpa->b[i];
1300                 // 0x4E Source Link-layer Address
1301                 //*ptr++ = 0x01;                // Option Type 1 == Source Link-layer Address
1302                 //*ptr++ = 0x01;                // Option length 1 (in units of 8 octets)
1303                 //for (i=0; i<6; i++) *ptr++ = (tha ? *tha : intf->MAC).b[i];
1304                 }
1305         else
1306                 {
1307                 // 0x3E NDP target.
1308                 for (i=0; i<16; i++) *ptr++ = spa->b[i];
1309                 // 0x4E Target Link-layer Address
1310                 *ptr++ = 0x02;          // Option Type 2 == Target Link-layer Address
1311                 *ptr++ = 0x01;          // Option length 1 (in units of 8 octets)
1312                 for (i=0; i<6; i++) *ptr++ = (tha ? *tha : intf->MAC).b[i];
1313                 }
1314
1315         // 0x4E or 0x56 Total NDP Packet length 78 or 86 bytes
1316         m->omsg.data[0x13] = ptr - &m->omsg.data[0x36];         // Compute actual length
1317         checksum.NotAnInteger = ~IPv6CheckSum(spa, v6dst, 0x3A, &m->omsg.data[0x36], m->omsg.data[0x13]);
1318         m->omsg.data[0x38] = checksum.b[0];
1319         m->omsg.data[0x39] = checksum.b[1];
1320
1321         mDNSPlatformSendRawPacket(m->omsg.data, ptr, rr->resrec.InterfaceID);
1322         }
1323
1324 mDNSlocal void SetupOwnerOpt(const mDNS *const m, const NetworkInterfaceInfo *const intf, rdataOPT *const owner)
1325         {
1326         owner->u.owner.vers     = 0;
1327         owner->u.owner.seq      = m->SleepSeqNum;
1328         owner->u.owner.HMAC     = m->PrimaryMAC;
1329         owner->u.owner.IMAC     = intf->MAC;
1330         owner->u.owner.password = zeroEthAddr;
1331
1332         // Don't try to compute the optlen until *after* we've set up the data fields
1333         // 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
1334         owner->opt              = kDNSOpt_Owner;
1335         owner->optlen           = DNSOpt_Owner_Space(&m->PrimaryMAC, &intf->MAC) - 4;
1336         }
1337
1338 mDNSlocal void GrantUpdateCredit(AuthRecord *rr)
1339         {
1340         if (++rr->UpdateCredits >= kMaxUpdateCredits) rr->NextUpdateCredit = 0;
1341         else rr->NextUpdateCredit = NonZeroTime(rr->NextUpdateCredit + kUpdateCreditRefreshInterval);
1342         }
1343
1344 // Note about acceleration of announcements to facilitate automatic coalescing of
1345 // multiple independent threads of announcements into a single synchronized thread:
1346 // The announcements in the packet may be at different stages of maturity;
1347 // One-second interval, two-second interval, four-second interval, and so on.
1348 // After we've put in all the announcements that are due, we then consider
1349 // whether there are other nearly-due announcements that are worth accelerating.
1350 // To be eligible for acceleration, a record MUST NOT be older (further along
1351 // its timeline) than the most mature record we've already put in the packet.
1352 // In other words, younger records can have their timelines accelerated to catch up
1353 // with their elder bretheren; this narrows the age gap and helps them eventually get in sync.
1354 // Older records cannot have their timelines accelerated; this would just widen
1355 // the gap between them and their younger bretheren and get them even more out of sync.
1356
1357 // Note: SendResponses calls mDNS_Deregister_internal which can call a user callback, which may change
1358 // the record list and/or question list.
1359 // Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
1360 mDNSlocal void SendResponses(mDNS *const m)
1361         {
1362         int pktcount = 0;
1363         AuthRecord *rr, *r2;
1364         mDNSs32 maxExistingAnnounceInterval = 0;
1365         const NetworkInterfaceInfo *intf = GetFirstActiveInterface(m->HostInterfaces);
1366
1367         m->NextScheduledResponse = m->timenow + 0x78000000;
1368
1369         if (m->SleepState == SleepState_Transferring) RetrySPSRegistrations(m);
1370
1371         for (rr = m->ResourceRecords; rr; rr=rr->next)
1372                 if (rr->ImmedUnicast)
1373                         {
1374                         mDNSAddr v4 = { mDNSAddrType_IPv4, {{{0}}} };
1375                         mDNSAddr v6 = { mDNSAddrType_IPv6, {{{0}}} };
1376                         v4.ip.v4 = rr->v4Requester;
1377                         v6.ip.v6 = rr->v6Requester;
1378                         if (!mDNSIPv4AddressIsZero(rr->v4Requester)) SendDelayedUnicastResponse(m, &v4, rr->ImmedAnswer);
1379                         if (!mDNSIPv6AddressIsZero(rr->v6Requester)) SendDelayedUnicastResponse(m, &v6, rr->ImmedAnswer);
1380                         if (rr->ImmedUnicast)
1381                                 {
1382                                 LogMsg("SendResponses: ERROR: rr->ImmedUnicast still set: %s", ARDisplayString(m, rr));
1383                                 rr->ImmedUnicast = mDNSfalse;
1384                                 }
1385                         }
1386
1387         // ***
1388         // *** 1. Setup: Set the SendRNow and ImmedAnswer fields to indicate which interface(s) the records need to be sent on
1389         // ***
1390
1391         // Run through our list of records, and decide which ones we're going to announce on all interfaces
1392         for (rr = m->ResourceRecords; rr; rr=rr->next)
1393                 {
1394                 while (rr->NextUpdateCredit && m->timenow - rr->NextUpdateCredit >= 0) GrantUpdateCredit(rr);
1395                 if (TimeToAnnounceThisRecord(rr, m->timenow))
1396                         {
1397                         if (rr->resrec.RecordType == kDNSRecordTypeDeregistering)
1398                                 {
1399                                 if (!rr->WakeUp.HMAC.l[0])
1400                                         rr->ImmedAnswer = mDNSInterfaceMark;            // Send goodbye packet on all interfaces
1401                                 else
1402                                         {
1403                                         LogSPS("SendResponses: Sending wakeup %2d for %.6a %s", rr->AnnounceCount-3, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
1404                                         SendWakeup(m, rr->resrec.InterfaceID, &rr->WakeUp.IMAC, &rr->WakeUp.password);
1405                                         for (r2 = rr; r2; r2=r2->next)
1406                                                 if (r2->AnnounceCount && r2->resrec.InterfaceID == rr->resrec.InterfaceID && mDNSSameEthAddress(&r2->WakeUp.IMAC, &rr->WakeUp.IMAC))
1407                                                         {
1408                                                         if (r2->AddressProxy.type == mDNSAddrType_IPv6)
1409                                                                 {
1410                                                                 #if MDNS_USE_Unsolicited_Neighbor_Advertisements
1411                                                                 LogSPS("NDP Announcement %2d Releasing traffic for H-MAC %.6a I-MAC %.6a %s",
1412                                                                         r2->AnnounceCount-3, &r2->WakeUp.HMAC, &r2->WakeUp.IMAC, ARDisplayString(m,r2));
1413                                                                 // Neighbor Advertisement; Override flag
1414                                                                 SendNDP(m, 0x88, 0x20, r2, &r2->AddressProxy.ip.v6, &r2->WakeUp.IMAC, &AllHosts_v6, &AllHosts_v6_Eth);
1415                                                                 #endif
1416                                                                 }
1417                                                         r2->LastAPTime = m->timenow;
1418                                                         if (r2->AnnounceCount-- <= 4) r2->WakeUp.HMAC = zeroEthAddr;
1419                                                         }
1420                                         }
1421                                 }
1422                         else if (ResourceRecordIsValidAnswer(rr))
1423                                 {
1424                                 if (rr->AddressProxy.type)
1425                                         {
1426                                         rr->AnnounceCount--;
1427                                         rr->ThisAPInterval *= 2;
1428                                         rr->LastAPTime = m->timenow;
1429                                         if (rr->AddressProxy.type == mDNSAddrType_IPv4)
1430                                                 {
1431                                                 LogSPS("ARP Announcement %2d Capturing traffic for H-MAC %.6a I-MAC %.6a %s",
1432                                                         rr->AnnounceCount, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m,rr));
1433                                                 SendARP(m, 1, rr, &rr->AddressProxy.ip.v4, &zeroEthAddr, &rr->AddressProxy.ip.v4, &onesEthAddr);
1434                                                 }
1435                                         else if (rr->AddressProxy.type == mDNSAddrType_IPv6)
1436                                                 {
1437                                                 #if MDNS_USE_Unsolicited_Neighbor_Advertisements
1438                                                 LogSPS("NDP Announcement %2d Capturing traffic for H-MAC %.6a I-MAC %.6a %s",
1439                                                         rr->AnnounceCount, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m,rr));
1440                                                 // Neighbor Advertisement; Override flag
1441                                                 SendNDP(m, 0x88, 0x20, rr, &rr->AddressProxy.ip.v6, mDNSNULL, &AllHosts_v6, &AllHosts_v6_Eth);
1442                                                 #endif
1443                                                 }
1444                                         }
1445                                 else
1446                                         {
1447                                         rr->ImmedAnswer = mDNSInterfaceMark;            // Send on all interfaces
1448                                         if (maxExistingAnnounceInterval < rr->ThisAPInterval)
1449                                                 maxExistingAnnounceInterval = rr->ThisAPInterval;
1450                                         if (rr->UpdateBlocked) rr->UpdateBlocked = 0;
1451                                         }
1452                                 }
1453                         }
1454                 }
1455
1456         // Any interface-specific records we're going to send are marked as being sent on all appropriate interfaces (which is just one)
1457         // Eligible records that are more than half-way to their announcement time are accelerated
1458         for (rr = m->ResourceRecords; rr; rr=rr->next)
1459                 if ((rr->resrec.InterfaceID && rr->ImmedAnswer) ||
1460                         (rr->ThisAPInterval <= maxExistingAnnounceInterval &&
1461                         TimeToAnnounceThisRecord(rr, m->timenow + rr->ThisAPInterval/2) &&
1462                         !rr->AddressProxy.type &&                                       // Don't include ARP Annoucements when considering which records to accelerate
1463                         ResourceRecordIsValidAnswer(rr)))
1464                         rr->ImmedAnswer = mDNSInterfaceMark;            // Send on all interfaces
1465
1466         // When sending SRV records (particularly when announcing a new service) automatically add related Address record(s) as additionals
1467         // Note: Currently all address records are interface-specific, so it's safe to set ImmedAdditional to their InterfaceID,
1468         // which will be non-null. If by some chance there is an address record that's not interface-specific (should never happen)
1469         // then all that means is that it won't get sent -- which would not be the end of the world.
1470         for (rr = m->ResourceRecords; rr; rr=rr->next)
1471                 {
1472                 if (rr->ImmedAnswer && rr->resrec.rrtype == kDNSType_SRV)
1473                         for (r2=m->ResourceRecords; r2; r2=r2->next)                            // Scan list of resource records
1474                                 if (RRTypeIsAddressType(r2->resrec.rrtype) &&                   // For all address records (A/AAAA) ...
1475                                         ResourceRecordIsValidAnswer(r2) &&                                      // ... which are valid for answer ...
1476                                         rr->LastMCTime - r2->LastMCTime >= 0 &&                         // ... which we have not sent recently ...
1477                                         rr->resrec.rdatahash == r2->resrec.namehash &&          // ... whose name is the name of the SRV target
1478                                         SameDomainName(&rr->resrec.rdata->u.srv.target, r2->resrec.name) &&
1479                                         (rr->ImmedAnswer == mDNSInterfaceMark || rr->ImmedAnswer == r2->resrec.InterfaceID))
1480                                         r2->ImmedAdditional = r2->resrec.InterfaceID;           // ... then mark this address record for sending too
1481                 // We also make sure we send the DeviceInfo TXT record too, if necessary
1482                 // We check for RecordType == kDNSRecordTypeShared because we don't want to tag the
1483                 // DeviceInfo TXT record onto a goodbye packet (RecordType == kDNSRecordTypeDeregistering).
1484                 if (rr->ImmedAnswer && rr->resrec.RecordType == kDNSRecordTypeShared && rr->resrec.rrtype == kDNSType_PTR)
1485                         if (ResourceRecordIsValidAnswer(&m->DeviceInfo) && SameDomainLabel(rr->resrec.rdata->u.name.c, m->DeviceInfo.resrec.name->c))
1486                                 {
1487                                 if (!m->DeviceInfo.ImmedAnswer) m->DeviceInfo.ImmedAnswer = rr->ImmedAnswer;
1488                                 else                            m->DeviceInfo.ImmedAnswer = mDNSInterfaceMark;
1489                                 }
1490                 }
1491
1492         // If there's a record which is supposed to be unique that we're going to send, then make sure that we give
1493         // the whole RRSet as an atomic unit. That means that if we have any other records with the same name/type/class
1494         // then we need to mark them for sending too. Otherwise, if we set the kDNSClass_UniqueRRSet bit on a
1495         // record, then other RRSet members that have not been sent recently will get flushed out of client caches.
1496         // -- 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
1497         // -- If any record is marked to be sent on all interfaces, make sure the whole set is marked to be sent on all interfaces
1498         for (rr = m->ResourceRecords; rr; rr=rr->next)
1499                 if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
1500                         {
1501                         if (rr->ImmedAnswer)                    // If we're sending this as answer, see that its whole RRSet is similarly marked
1502                                 {
1503                                 for (r2 = m->ResourceRecords; r2; r2=r2->next)
1504                                         if (ResourceRecordIsValidAnswer(r2))
1505                                                 if (r2->ImmedAnswer != mDNSInterfaceMark &&
1506                                                         r2->ImmedAnswer != rr->ImmedAnswer && SameResourceRecordSignature(r2, rr))
1507                                                         r2->ImmedAnswer = !r2->ImmedAnswer ? rr->ImmedAnswer : mDNSInterfaceMark;
1508                                 }
1509                         else if (rr->ImmedAdditional)   // If we're sending this as additional, see that its whole RRSet is similarly marked
1510                                 {
1511                                 for (r2 = m->ResourceRecords; r2; r2=r2->next)
1512                                         if (ResourceRecordIsValidAnswer(r2))
1513                                                 if (r2->ImmedAdditional != rr->ImmedAdditional && SameResourceRecordSignature(r2, rr))
1514                                                         r2->ImmedAdditional = rr->ImmedAdditional;
1515                                 }
1516                         }
1517
1518         // Now set SendRNow state appropriately
1519         for (rr = m->ResourceRecords; rr; rr=rr->next)
1520                 {
1521                 if (rr->ImmedAnswer == mDNSInterfaceMark)               // Sending this record on all appropriate interfaces
1522                         {
1523                         rr->SendRNow = !intf ? mDNSNULL : (rr->resrec.InterfaceID) ? rr->resrec.InterfaceID : intf->InterfaceID;
1524                         rr->ImmedAdditional = mDNSNULL;                         // No need to send as additional if sending as answer
1525                         rr->LastMCTime      = m->timenow;
1526                         rr->LastMCInterface = rr->ImmedAnswer;
1527                         // If we're announcing this record, and it's at least half-way to its ordained time, then consider this announcement done
1528                         if (TimeToAnnounceThisRecord(rr, m->timenow + rr->ThisAPInterval/2))
1529                                 {
1530                                 rr->AnnounceCount--;
1531                                 if (rr->resrec.RecordType != kDNSRecordTypeDeregistering)
1532                                         rr->ThisAPInterval *= 2;
1533                                 rr->LastAPTime = m->timenow;
1534                                 debugf("Announcing %##s (%s) %d", rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype), rr->AnnounceCount);
1535                                 }
1536                         }
1537                 else if (rr->ImmedAnswer)                                               // Else, just respond to a single query on single interface:
1538                         {
1539                         rr->SendRNow        = rr->ImmedAnswer;          // Just respond on that interface
1540                         rr->ImmedAdditional = mDNSNULL;                         // No need to send as additional too
1541                         rr->LastMCTime      = m->timenow;
1542                         rr->LastMCInterface = rr->ImmedAnswer;
1543                         }
1544                 SetNextAnnounceProbeTime(m, rr);
1545                 //if (rr->SendRNow) LogMsg("%-15.4a %s", &rr->v4Requester, ARDisplayString(m, rr));
1546                 }
1547
1548         // ***
1549         // *** 2. Loop through interface list, sending records as appropriate
1550         // ***
1551
1552         while (intf)
1553                 {
1554                 const int OwnerRecordSpace = (m->AnnounceOwner && intf->MAC.l[0]) ? DNSOpt_Header_Space + DNSOpt_Owner_Space(&m->PrimaryMAC, &intf->MAC) : 0;
1555                 int numDereg    = 0;
1556                 int numAnnounce = 0;
1557                 int numAnswer   = 0;
1558                 mDNSu8 *responseptr = m->omsg.data;
1559                 mDNSu8 *newptr;
1560                 InitializeDNSMessage(&m->omsg.h, zeroID, ResponseFlags);
1561         
1562                 // First Pass. Look for:
1563                 // 1. Deregistering records that need to send their goodbye packet
1564                 // 2. Updated records that need to retract their old data
1565                 // 3. Answers and announcements we need to send
1566                 for (rr = m->ResourceRecords; rr; rr=rr->next)
1567                         {
1568                         if (rr->SendRNow == intf->InterfaceID)
1569                                 {
1570                                 newptr = mDNSNULL;
1571                                 if (rr->resrec.RecordType == kDNSRecordTypeDeregistering)
1572                                         {
1573                                         newptr = PutRR_OS_TTL(responseptr, &m->omsg.h.numAnswers, &rr->resrec, 0);
1574                                         if (newptr) { responseptr = newptr; numDereg++; }
1575                                         }
1576                                 else if (rr->NewRData && !m->SleepState)                                        // If we have new data for this record
1577                                         {
1578                                         RData *OldRData     = rr->resrec.rdata;
1579                                         mDNSu16 oldrdlength = rr->resrec.rdlength;
1580                                         // See if we should send a courtesy "goodbye" for the old data before we replace it.
1581                                         if (ResourceRecordIsValidAnswer(rr) && rr->RequireGoodbye)
1582                                                 {
1583                                                 newptr = PutRR_OS_TTL(responseptr, &m->omsg.h.numAnswers, &rr->resrec, 0);
1584                                                 if (newptr) { responseptr = newptr; numDereg++; rr->RequireGoodbye = mDNSfalse; }
1585                                                 }
1586                                         // Now try to see if we can fit the update in the same packet (not fatal if we can't)
1587                                         SetNewRData(&rr->resrec, rr->NewRData, rr->newrdlength);
1588                                         if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
1589                                                 rr->resrec.rrclass |= kDNSClass_UniqueRRSet;            // Temporarily set the cache flush bit so PutResourceRecord will set it
1590                                         newptr = PutRR_OS(responseptr, &m->omsg.h.numAnswers, &rr->resrec);
1591                                         rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet;                   // Make sure to clear cache flush bit back to normal state
1592                                         if (newptr) { responseptr = newptr; rr->RequireGoodbye = mDNStrue; }
1593                                         SetNewRData(&rr->resrec, OldRData, oldrdlength);
1594                                         }
1595                                 else
1596                                         {
1597                                         mDNSu8 active = (mDNSu8)
1598                                                 (m->SleepState != SleepState_Sleeping || intf->SPSAddr[0].type || intf->SPSAddr[1].type || intf->SPSAddr[2].type);
1599                                         if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
1600                                                 rr->resrec.rrclass |= kDNSClass_UniqueRRSet;            // Temporarily set the cache flush bit so PutResourceRecord will set it
1601                                         newptr = PutRR_OS_TTL(responseptr, &m->omsg.h.numAnswers, &rr->resrec, active ? rr->resrec.rroriginalttl : 0);
1602                                         rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet;                   // Make sure to clear cache flush bit back to normal state
1603                                         if (newptr)
1604                                                 {
1605                                                 responseptr = newptr;
1606                                                 rr->RequireGoodbye = active;
1607                                                 if (rr->LastAPTime == m->timenow) numAnnounce++; else numAnswer++;
1608                                                 }
1609
1610                                         // The first time through (pktcount==0), if this record is verified unique
1611                                         // (i.e. typically A, AAAA, SRV and TXT), set the flag to add an NSEC too.
1612                                         if (!pktcount && active && rr->resrec.RecordType == kDNSRecordTypeVerified && !rr->SendNSECNow) rr->SendNSECNow = mDNSInterfaceMark;
1613                                         }
1614
1615                                 if (newptr)             // If succeeded in sending, advance to next interface
1616                                         {
1617                                         // If sending on all interfaces, go to next interface; else we're finished now
1618                                         if (rr->ImmedAnswer == mDNSInterfaceMark && rr->resrec.InterfaceID == mDNSInterface_Any)
1619                                                 rr->SendRNow = GetNextActiveInterfaceID(intf);
1620                                         else
1621                                                 rr->SendRNow = mDNSNULL;
1622                                         }
1623                                 }
1624                         }
1625         
1626                 // Second Pass. Add additional records, if there's space.
1627                 newptr = responseptr;
1628                 for (rr = m->ResourceRecords; rr; rr=rr->next)
1629                         if (rr->ImmedAdditional == intf->InterfaceID)
1630                                 if (ResourceRecordIsValidAnswer(rr))
1631                                         {
1632                                         // If we have at least one answer already in the packet, then plan to add additionals too
1633                                         mDNSBool SendAdditional = (m->omsg.h.numAnswers > 0);
1634                                         
1635                                         // If we're not planning to send any additionals, but this record is a unique one, then
1636                                         // make sure we haven't already sent any other members of its RRSet -- if we have, then they
1637                                         // will have had the cache flush bit set, so now we need to finish the job and send the rest.
1638                                         if (!SendAdditional && (rr->resrec.RecordType & kDNSRecordTypeUniqueMask))
1639                                                 {
1640                                                 const AuthRecord *a;
1641                                                 for (a = m->ResourceRecords; a; a=a->next)
1642                                                         if (a->LastMCTime      == m->timenow &&
1643                                                                 a->LastMCInterface == intf->InterfaceID &&
1644                                                                 SameResourceRecordSignature(a, rr)) { SendAdditional = mDNStrue; break; }
1645                                                 }
1646                                         if (!SendAdditional)                                    // If we don't want to send this after all,
1647                                                 rr->ImmedAdditional = mDNSNULL;         // then cancel its ImmedAdditional field
1648                                         else if (newptr)                                                // Else, try to add it if we can
1649                                                 {
1650                                                 // The first time through (pktcount==0), if this record is verified unique
1651                                                 // (i.e. typically A, AAAA, SRV and TXT), set the flag to add an NSEC too.
1652                                                 if (!pktcount && rr->resrec.RecordType == kDNSRecordTypeVerified && !rr->SendNSECNow) rr->SendNSECNow = mDNSInterfaceMark;
1653
1654                                                 if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
1655                                                         rr->resrec.rrclass |= kDNSClass_UniqueRRSet;    // Temporarily set the cache flush bit so PutResourceRecord will set it
1656                                                 newptr = PutRR_OS(newptr, &m->omsg.h.numAdditionals, &rr->resrec);
1657                                                 rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet;           // Make sure to clear cache flush bit back to normal state
1658                                                 if (newptr)
1659                                                         {
1660                                                         responseptr = newptr;
1661                                                         rr->ImmedAdditional = mDNSNULL;
1662                                                         rr->RequireGoodbye = mDNStrue;
1663                                                         // If we successfully put this additional record in the packet, we record LastMCTime & LastMCInterface.
1664                                                         // This matters particularly in the case where we have more than one IPv6 (or IPv4) address, because otherwise,
1665                                                         // when we see our own multicast with the cache flush bit set, if we haven't set LastMCTime, then we'll get
1666                                                         // all concerned and re-announce our record again to make sure it doesn't get flushed from peer caches.
1667                                                         rr->LastMCTime      = m->timenow;
1668                                                         rr->LastMCInterface = intf->InterfaceID;
1669                                                         }
1670                                                 }
1671                                         }
1672
1673                 // Third Pass. Add NSEC records, if there's space.
1674                 for (rr = m->ResourceRecords; rr; rr=rr->next)
1675                         if (rr->SendNSECNow == mDNSInterfaceMark || rr->SendNSECNow == intf->InterfaceID)
1676                                 {
1677                                 AuthRecord nsec;
1678                                 mDNS_SetupResourceRecord(&nsec, mDNSNULL, mDNSInterface_Any, kDNSType_NSEC, rr->resrec.rroriginalttl, kDNSRecordTypeUnique, mDNSNULL, mDNSNULL);
1679                                 nsec.resrec.rrclass |= kDNSClass_UniqueRRSet;
1680                                 AssignDomainName(&nsec.namestorage, rr->resrec.name);
1681                                 mDNSPlatformMemZero(nsec.rdatastorage.u.nsec.bitmap, sizeof(nsec.rdatastorage.u.nsec.bitmap));
1682                                 for (r2 = m->ResourceRecords; r2; r2=r2->next)
1683                                         if (ResourceRecordIsValidAnswer(r2) && SameResourceRecordNameClassInterface(r2, rr))
1684                                                 {
1685                                                 if (r2->resrec.rrtype >= kDNSQType_ANY) { LogMsg("Can't create NSEC for record %s", ARDisplayString(m, r2)); break; }
1686                                                 else nsec.rdatastorage.u.nsec.bitmap[r2->resrec.rrtype >> 3] |= 128 >> (r2->resrec.rrtype & 7);
1687                                                 }
1688                                 newptr = responseptr;
1689                                 if (!r2)        // If we successfully built our NSEC record, add it to the packet now
1690                                         {
1691                                         newptr = PutRR_OS(responseptr, &m->omsg.h.numAdditionals, &nsec.resrec);
1692                                         if (newptr) responseptr = newptr;
1693                                         }
1694
1695                                 // If we successfully put the NSEC record, clear the SendNSECNow flag
1696                                 // If we consider this NSEC optional, then we unconditionally clear the SendNSECNow flag, even if we fail to put this additional record
1697                                 if (newptr || rr->SendNSECNow == mDNSInterfaceMark)
1698                                         {
1699                                         rr->SendNSECNow = mDNSNULL;
1700                                         // Run through remainder of list clearing SendNSECNow flag for all other records which would generate the same NSEC
1701                                         for (r2 = rr->next; r2; r2=r2->next)
1702                                                 if (SameResourceRecordNameClassInterface(r2, rr))
1703                                                         if (r2->SendNSECNow == mDNSInterfaceMark || r2->SendNSECNow == intf->InterfaceID)
1704                                                                 r2->SendNSECNow = mDNSNULL;
1705                                         }
1706                                 }
1707
1708                 if (m->omsg.h.numAnswers || m->omsg.h.numAdditionals)
1709                         {
1710                         // If we have data to send, add OWNER option if necessary, then send packet
1711
1712                         if (OwnerRecordSpace)
1713                                 {
1714                                 AuthRecord opt;
1715                                 mDNS_SetupResourceRecord(&opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, mDNSNULL, mDNSNULL);
1716                                 opt.resrec.rrclass    = NormalMaxDNSMessageData;
1717                                 opt.resrec.rdlength   = sizeof(rdataOPT);       // One option in this OPT record
1718                                 opt.resrec.rdestimate = sizeof(rdataOPT);
1719                                 SetupOwnerOpt(m, intf, &opt.resrec.rdata->u.opt[0]);
1720                                 newptr = PutResourceRecord(&m->omsg, responseptr, &m->omsg.h.numAdditionals, &opt.resrec);
1721                                 if (newptr) { responseptr = newptr; LogSPS("SendResponses put %s", ARDisplayString(m, &opt)); }
1722                                 else LogMsg("SendResponses: How did we fail to have space for the OPT record (%d/%d/%d/%d) %s",
1723                                         m->omsg.h.numQuestions, m->omsg.h.numAnswers, m->omsg.h.numAuthorities, m->omsg.h.numAdditionals, ARDisplayString(m, &opt));
1724                                 }
1725
1726                         debugf("SendResponses: Sending %d Deregistration%s, %d Announcement%s, %d Answer%s, %d Additional%s on %p",
1727                                 numDereg,                 numDereg                 == 1 ? "" : "s",
1728                                 numAnnounce,              numAnnounce              == 1 ? "" : "s",
1729                                 numAnswer,                numAnswer                == 1 ? "" : "s",
1730                                 m->omsg.h.numAdditionals, m->omsg.h.numAdditionals == 1 ? "" : "s", intf->InterfaceID);
1731                         if (intf->IPv4Available) mDNSSendDNSMessage(m, &m->omsg, responseptr, intf->InterfaceID, mDNSNULL, &AllDNSLinkGroup_v4, MulticastDNSPort, mDNSNULL, mDNSNULL);
1732                         if (intf->IPv6Available) mDNSSendDNSMessage(m, &m->omsg, responseptr, intf->InterfaceID, mDNSNULL, &AllDNSLinkGroup_v6, MulticastDNSPort, mDNSNULL, mDNSNULL);
1733                         if (!m->SuppressSending) m->SuppressSending = NonZeroTime(m->timenow + (mDNSPlatformOneSecond+9)/10);
1734                         if (++pktcount >= 1000) { LogMsg("SendResponses exceeded loop limit %d: giving up", pktcount); break; }
1735                         // There might be more things to send on this interface, so go around one more time and try again.
1736                         }
1737                 else    // Nothing more to send on this interface; go to next
1738                         {
1739                         const NetworkInterfaceInfo *next = GetFirstActiveInterface(intf->next);
1740                         #if MDNS_DEBUGMSGS && 0
1741                         const char *const msg = next ? "SendResponses: Nothing more on %p; moving to %p" : "SendResponses: Nothing more on %p";
1742                         debugf(msg, intf, next);
1743                         #endif
1744                         intf = next;
1745                         pktcount = 0;           // When we move to a new interface, reset packet count back to zero -- NSEC generation logic uses it
1746                         }
1747                 }
1748
1749         // ***
1750         // *** 3. Cleanup: Now that everything is sent, call client callback functions, and reset state variables
1751         // ***
1752
1753         if (m->CurrentRecord)
1754                 LogMsg("SendResponses ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
1755         m->CurrentRecord = m->ResourceRecords;
1756         while (m->CurrentRecord)
1757                 {
1758                 rr = m->CurrentRecord;
1759                 m->CurrentRecord = rr->next;
1760
1761                 if (rr->SendRNow)
1762                         {
1763                         if (rr->resrec.InterfaceID != mDNSInterface_LocalOnly)
1764                                 LogMsg("SendResponses: No active interface to send: %02X %s", rr->resrec.RecordType, ARDisplayString(m, rr));
1765                         rr->SendRNow = mDNSNULL;
1766                         }
1767
1768                 if (rr->ImmedAnswer || rr->resrec.RecordType == kDNSRecordTypeDeregistering)
1769                         {
1770                         if (rr->NewRData) CompleteRDataUpdate(m, rr);   // Update our rdata, clear the NewRData pointer, and return memory to the client
1771         
1772                         if (rr->resrec.RecordType == kDNSRecordTypeDeregistering && rr->AnnounceCount == 0)
1773                                 CompleteDeregistration(m, rr);          // Don't touch rr after this
1774                         else
1775                                 {
1776                                 rr->ImmedAnswer  = mDNSNULL;
1777                                 rr->ImmedUnicast = mDNSfalse;
1778                                 rr->v4Requester  = zerov4Addr;
1779                                 rr->v6Requester  = zerov6Addr;
1780                                 }
1781                         }
1782                 }
1783         verbosedebugf("SendResponses: Next in %ld ticks", m->NextScheduledResponse - m->timenow);
1784         }
1785
1786 // Calling CheckCacheExpiration() is an expensive operation because it has to look at the entire cache,
1787 // so we want to be lazy about how frequently we do it.
1788 // 1. If a cache record is currently referenced by *no* active questions,
1789 //    then we don't mind expiring it up to a minute late (who will know?)
1790 // 2. Else, if a cache record is due for some of its final expiration queries,
1791 //    we'll allow them to be late by up to 2% of the TTL
1792 // 3. Else, if a cache record has completed all its final expiration queries without success,
1793 //    and is expiring, and had an original TTL more than ten seconds, we'll allow it to be one second late
1794 // 4. Else, it is expiring and had an original TTL of ten seconds or less (includes explicit goodbye packets),
1795 //    so allow at most 1/10 second lateness
1796 // 5. For records with rroriginalttl set to zero, that means we really want to delete them immediately
1797 //    (we have a new record with DelayDelivery set, waiting for the old record to go away before we can notify clients).
1798 #define CacheCheckGracePeriod(RR) (                                                   \
1799         ((RR)->DelayDelivery                           ) ? (mDNSPlatformOneSecond/10)   : \
1800         ((RR)->CRActiveQuestion == mDNSNULL            ) ? (60 * mDNSPlatformOneSecond) : \
1801         ((RR)->UnansweredQueries < MaxUnansweredQueries) ? (TicksTTL(rr)/50)            : \
1802         ((RR)->resrec.rroriginalttl > 10               ) ? (mDNSPlatformOneSecond)      : \
1803         ((RR)->resrec.rroriginalttl > 0                ) ? (mDNSPlatformOneSecond/10)   : 0)
1804
1805 // Note: MUST call SetNextCacheCheckTime any time we change:
1806 // rr->TimeRcvd
1807 // rr->resrec.rroriginalttl
1808 // rr->UnansweredQueries
1809 // rr->CRActiveQuestion
1810 // Also, any time we set rr->DelayDelivery we should call SetNextCacheCheckTime to ensure m->NextCacheCheck is set if necessary
1811 // Clearing rr->DelayDelivery does not require a call to SetNextCacheCheckTime
1812 mDNSlocal void SetNextCacheCheckTime(mDNS *const m, CacheRecord *const rr)
1813         {
1814         rr->NextRequiredQuery = RRExpireTime(rr);
1815
1816         // If we have an active question, then see if we want to schedule a refresher query for this record.
1817         // Usually we expect to do four queries, at 80-82%, 85-87%, 90-92% and then 95-97% of the TTL.
1818         if (rr->CRActiveQuestion && rr->UnansweredQueries < MaxUnansweredQueries)
1819                 {
1820                 rr->NextRequiredQuery -= TicksTTL(rr)/20 * (MaxUnansweredQueries - rr->UnansweredQueries);
1821                 rr->NextRequiredQuery += mDNSRandom((mDNSu32)TicksTTL(rr)/50);
1822                 verbosedebugf("SetNextCacheCheckTime: %##s (%s) NextRequiredQuery in %ld sec CacheCheckGracePeriod %d ticks",
1823                         rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype),
1824                         (rr->NextRequiredQuery - m->timenow) / mDNSPlatformOneSecond, CacheCheckGracePeriod(rr));
1825                 }
1826
1827         if (m->NextCacheCheck - (rr->NextRequiredQuery + CacheCheckGracePeriod(rr)) > 0)
1828                 m->NextCacheCheck = (rr->NextRequiredQuery + CacheCheckGracePeriod(rr));
1829         
1830         if (rr->DelayDelivery)
1831                 if (m->NextCacheCheck - rr->DelayDelivery > 0)
1832                         m->NextCacheCheck = rr->DelayDelivery;
1833         }
1834
1835 #define kMinimumReconfirmTime                     ((mDNSu32)mDNSPlatformOneSecond *  5)
1836 #define kDefaultReconfirmTimeForWake              ((mDNSu32)mDNSPlatformOneSecond *  5)
1837 #define kDefaultReconfirmTimeForNoAnswer          ((mDNSu32)mDNSPlatformOneSecond *  5)
1838 #define kDefaultReconfirmTimeForFlappingInterface ((mDNSu32)mDNSPlatformOneSecond * 30)
1839
1840 mDNSlocal mStatus mDNS_Reconfirm_internal(mDNS *const m, CacheRecord *const rr, mDNSu32 interval)
1841         {
1842         if (interval < kMinimumReconfirmTime)
1843                 interval = kMinimumReconfirmTime;
1844         if (interval > 0x10000000)      // Make sure interval doesn't overflow when we multiply by four below
1845                 interval = 0x10000000;
1846
1847         // If the expected expiration time for this record is more than interval+33%, then accelerate its expiration
1848         if (RRExpireTime(rr) - m->timenow > (mDNSs32)((interval * 4) / 3))
1849                 {
1850                 // Add a 33% random amount to the interval, to avoid synchronization between multiple hosts
1851                 // For all the reconfirmations in a given batch, we want to use the same random value
1852                 // so that the reconfirmation questions can be grouped into a single query packet
1853                 if (!m->RandomReconfirmDelay) m->RandomReconfirmDelay = 1 + mDNSRandom(0x3FFFFFFF);
1854                 interval += m->RandomReconfirmDelay % ((interval/3) + 1);
1855                 rr->TimeRcvd          = m->timenow - (mDNSs32)interval * 3;
1856                 rr->resrec.rroriginalttl     = (interval * 4 + mDNSPlatformOneSecond - 1) / mDNSPlatformOneSecond;
1857                 SetNextCacheCheckTime(m, rr);
1858                 }
1859         debugf("mDNS_Reconfirm_internal:%6ld ticks to go for %s %p",
1860                 RRExpireTime(rr) - m->timenow, CRDisplayString(m, rr), rr->CRActiveQuestion);
1861         return(mStatus_NoError);
1862         }
1863
1864 #define MaxQuestionInterval         (3600 * mDNSPlatformOneSecond)
1865
1866 // BuildQuestion puts a question into a DNS Query packet and if successful, updates the value of queryptr.
1867 // It also appends to the list of known answer records that need to be included,
1868 // and updates the forcast for the size of the known answer section.
1869 mDNSlocal mDNSBool BuildQuestion(mDNS *const m, DNSMessage *query, mDNSu8 **queryptr, DNSQuestion *q,
1870         CacheRecord ***kalistptrptr, mDNSu32 *answerforecast)
1871         {
1872         mDNSBool ucast = (q->LargeAnswers || q->RequestUnicast) && m->CanReceiveUnicastOn5353;
1873         mDNSu16 ucbit = (mDNSu16)(ucast ? kDNSQClass_UnicastResponse : 0);
1874         const mDNSu8 *const limit = query->data + NormalMaxDNSMessageData;
1875         mDNSu8 *newptr = putQuestion(query, *queryptr, limit - *answerforecast, &q->qname, q->qtype, (mDNSu16)(q->qclass | ucbit));
1876         if (!newptr)
1877                 {
1878                 debugf("BuildQuestion: No more space in this packet for question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
1879                 return(mDNSfalse);
1880                 }
1881         else
1882                 {
1883                 mDNSu32 forecast = *answerforecast;
1884                 const mDNSu32 slot = HashSlot(&q->qname);
1885                 const CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
1886                 CacheRecord *rr;
1887                 CacheRecord **ka = *kalistptrptr;       // Make a working copy of the pointer we're going to update
1888
1889                 for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)                         // If we have a resource record in our cache,
1890                         if (rr->resrec.InterfaceID == q->SendQNow &&                                    // received on this interface
1891                                 rr->NextInKAList == mDNSNULL && ka != &rr->NextInKAList &&      // which is not already in the known answer list
1892                                 rr->resrec.rdlength <= SmallRecordLimit &&                                      // which is small enough to sensibly fit in the packet
1893                                 SameNameRecordAnswersQuestion(&rr->resrec, q) &&                        // which answers our question
1894                                 rr->TimeRcvd + TicksTTL(rr)/2 - m->timenow >                            // and its half-way-to-expiry time is at least 1 second away
1895                                                                                                 mDNSPlatformOneSecond)          // (also ensures we never include goodbye records with TTL=1)
1896                                 {
1897                                 *ka = rr;       // Link this record into our known answer chain
1898                                 ka = &rr->NextInKAList;
1899                                 // We forecast: compressed name (2) type (2) class (2) TTL (4) rdlength (2) rdata (n)
1900                                 forecast += 12 + rr->resrec.rdestimate;
1901                                 // If we're trying to put more than one question in this packet, and it doesn't fit
1902                                 // then undo that last question and try again next time
1903                                 if (query->h.numQuestions > 1 && newptr + forecast >= limit)
1904                                         {
1905                                         debugf("BuildQuestion: Retracting question %##s (%s) new forecast total %d",
1906                                                 q->qname.c, DNSTypeName(q->qtype), newptr + forecast - query->data);
1907                                         query->h.numQuestions--;
1908                                         ka = *kalistptrptr;             // Go back to where we started and retract these answer records
1909                                         while (*ka) { CacheRecord *c = *ka; *ka = mDNSNULL; ka = &c->NextInKAList; }
1910                                         return(mDNSfalse);              // Return false, so we'll try again in the next packet
1911                                         }
1912                                 }
1913
1914                 // Success! Update our state pointers, increment UnansweredQueries as appropriate, and return
1915                 *queryptr        = newptr;                              // Update the packet pointer
1916                 *answerforecast  = forecast;                    // Update the forecast
1917                 *kalistptrptr    = ka;                                  // Update the known answer list pointer
1918                 if (ucast) q->ExpectUnicastResp = NonZeroTime(m->timenow);
1919
1920                 for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)                         // For every resource record in our cache,
1921                         if (rr->resrec.InterfaceID == q->SendQNow &&                                    // received on this interface
1922                                 rr->NextInKAList == mDNSNULL && ka != &rr->NextInKAList &&      // which is not in the known answer list
1923                                 SameNameRecordAnswersQuestion(&rr->resrec, q))                          // which answers our question
1924                                         {
1925                                         rr->UnansweredQueries++;                                                                // indicate that we're expecting a response
1926                                         rr->LastUnansweredTime = m->timenow;
1927                                         SetNextCacheCheckTime(m, rr);
1928                                         }
1929
1930                 return(mDNStrue);
1931                 }
1932         }
1933
1934 // When we have a query looking for a specified name, but there appear to be no answers with
1935 // that name, ReconfirmAntecedents() is called with depth=0 to start the reconfirmation process
1936 // for any records in our cache that reference the given name (e.g. PTR and SRV records).
1937 // For any such cache record we find, we also recursively call ReconfirmAntecedents() for *its* name.
1938 // We increment depth each time we recurse, to guard against possible infinite loops, with a limit of 5.
1939 // A typical reconfirmation scenario might go like this:
1940 // Depth 0: Name "myhost.local" has no address records
1941 // Depth 1: SRV "My Service._example._tcp.local." refers to "myhost.local"; may be stale
1942 // Depth 2: PTR "_example._tcp.local." refers to "My Service"; may be stale
1943 // Depth 3: PTR "_services._dns-sd._udp.local." refers to "_example._tcp.local."; may be stale
1944 // Currently depths 4 and 5 are not expected to occur; if we did get to depth 5 we'd reconfim any records we
1945 // found referring to the given name, but not recursively descend any further reconfirm *their* antecedents.
1946 mDNSlocal void ReconfirmAntecedents(mDNS *const m, const domainname *const name, const mDNSu32 namehash, const int depth)
1947         {
1948         mDNSu32 slot;
1949         CacheGroup *cg;
1950         CacheRecord *cr;
1951         debugf("ReconfirmAntecedents (depth=%d) for %##s", depth, name->c);
1952         FORALL_CACHERECORDS(slot, cg, cr)
1953                 {
1954                 domainname *crtarget = GetRRDomainNameTarget(&cr->resrec);
1955                 if (crtarget && cr->resrec.rdatahash == namehash && SameDomainName(crtarget, name))
1956                         {
1957                         LogInfo("ReconfirmAntecedents: Reconfirming (depth=%d) %s", depth, CRDisplayString(m, cr));
1958                         mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForNoAnswer);
1959                         if (depth < 5) ReconfirmAntecedents(m, cr->resrec.name, cr->resrec.namehash, depth+1);
1960                         }
1961                 }
1962         }
1963
1964 // If we get no answer for a AAAA query, then before doing an automatic implicit ReconfirmAntecedents
1965 // we check if we have an address record for the same name. If we do have an IPv4 address for a given
1966 // name but not an IPv6 address, that's okay (it just means the device doesn't do IPv6) so the failure
1967 // to get a AAAA response is not grounds to doubt the PTR/SRV chain that lead us to that name.
1968 mDNSlocal const CacheRecord *CacheHasAddressTypeForName(mDNS *const m, const domainname *const name, const mDNSu32 namehash)
1969         {
1970         CacheGroup *const cg = CacheGroupForName(m, HashSlot(name), namehash, name);
1971         const CacheRecord *cr = cg ? cg->members : mDNSNULL;
1972         while (cr && !RRTypeIsAddressType(cr->resrec.rrtype)) cr=cr->next;
1973         return(cr);
1974         }
1975
1976 mDNSlocal const CacheRecord *FindSPSInCache1(mDNS *const m, const DNSQuestion *const q, const CacheRecord *const c0, const CacheRecord *const c1)
1977         {
1978         CacheGroup *const cg = CacheGroupForName(m, HashSlot(&q->qname), q->qnamehash, &q->qname);
1979         const CacheRecord *cr, *bestcr = mDNSNULL;
1980         mDNSu32 bestmetric = 1000000;
1981         for (cr = cg ? cg->members : mDNSNULL; cr; cr=cr->next)
1982                 if (cr->resrec.rrtype == kDNSType_PTR && cr->resrec.rdlength >= 6)                                              // If record is PTR type, with long enough name,
1983                         if (cr != c0 && cr != c1)                                                                                                                       // that's not one we've seen before,
1984                                 if (SameNameRecordAnswersQuestion(&cr->resrec, q))                                                              // and answers our browse query,
1985                                         if (!IdenticalSameNameRecord(&cr->resrec, &m->SPSRecords.RR_PTR.resrec))        // and is not our own advertised service...
1986                                                 {
1987                                                 mDNSu32 metric = SPSMetric(cr->resrec.rdata->u.name.c);
1988                                                 if (bestmetric > metric) { bestmetric = metric; bestcr = cr; }
1989                                                 }
1990         return(bestcr);
1991         }
1992
1993 // Finds the three best Sleep Proxies we currently have in our cache
1994 mDNSexport void FindSPSInCache(mDNS *const m, const DNSQuestion *const q, const CacheRecord *sps[3])
1995         {
1996         sps[0] =                      FindSPSInCache1(m, q, mDNSNULL, mDNSNULL);
1997         sps[1] = !sps[0] ? mDNSNULL : FindSPSInCache1(m, q, sps[0],   mDNSNULL);
1998         sps[2] = !sps[1] ? mDNSNULL : FindSPSInCache1(m, q, sps[0],   sps[1]);
1999         }
2000
2001 // Only DupSuppressInfos newer than the specified 'time' are allowed to remain active
2002 mDNSlocal void ExpireDupSuppressInfo(DupSuppressInfo ds[DupSuppressInfoSize], mDNSs32 time)
2003         {
2004         int i;
2005         for (i=0; i<DupSuppressInfoSize; i++) if (ds[i].Time - time < 0) ds[i].InterfaceID = mDNSNULL;
2006         }
2007
2008 mDNSlocal void ExpireDupSuppressInfoOnInterface(DupSuppressInfo ds[DupSuppressInfoSize], mDNSs32 time, mDNSInterfaceID InterfaceID)
2009         {
2010         int i;
2011         for (i=0; i<DupSuppressInfoSize; i++) if (ds[i].InterfaceID == InterfaceID && ds[i].Time - time < 0) ds[i].InterfaceID = mDNSNULL;
2012         }
2013
2014 mDNSlocal mDNSBool SuppressOnThisInterface(const DupSuppressInfo ds[DupSuppressInfoSize], const NetworkInterfaceInfo * const intf)
2015         {
2016         int i;
2017         mDNSBool v4 = !intf->IPv4Available;             // If this interface doesn't do v4, we don't need to find a v4 duplicate of this query
2018         mDNSBool v6 = !intf->IPv6Available;             // If this interface doesn't do v6, we don't need to find a v6 duplicate of this query
2019         for (i=0; i<DupSuppressInfoSize; i++)
2020                 if (ds[i].InterfaceID == intf->InterfaceID)
2021                         {
2022                         if      (ds[i].Type == mDNSAddrType_IPv4) v4 = mDNStrue;
2023                         else if (ds[i].Type == mDNSAddrType_IPv6) v6 = mDNStrue;
2024                         if (v4 && v6) return(mDNStrue);
2025                         }
2026         return(mDNSfalse);
2027         }
2028
2029 mDNSlocal int RecordDupSuppressInfo(DupSuppressInfo ds[DupSuppressInfoSize], mDNSs32 Time, mDNSInterfaceID InterfaceID, mDNSs32 Type)
2030         {
2031         int i, j;
2032
2033         // See if we have this one in our list somewhere already
2034         for (i=0; i<DupSuppressInfoSize; i++) if (ds[i].InterfaceID == InterfaceID && ds[i].Type == Type) break;
2035
2036         // If not, find a slot we can re-use
2037         if (i >= DupSuppressInfoSize)
2038                 {
2039                 i = 0;
2040                 for (j=1; j<DupSuppressInfoSize && ds[i].InterfaceID; j++)
2041                         if (!ds[j].InterfaceID || ds[j].Time - ds[i].Time < 0)
2042                                 i = j;
2043                 }
2044         
2045         // Record the info about this query we saw
2046         ds[i].Time        = Time;
2047         ds[i].InterfaceID = InterfaceID;
2048         ds[i].Type        = Type;
2049         
2050         return(i);
2051         }
2052
2053 mDNSlocal mDNSBool AccelerateThisQuery(mDNS *const m, DNSQuestion *q)
2054         {
2055         // If more than 90% of the way to the query time, we should unconditionally accelerate it
2056         if (TimeToSendThisQuestion(q, m->timenow + q->ThisQInterval/10))
2057                 return(mDNStrue);
2058
2059         // If half-way to next scheduled query time, only accelerate if it will add less than 512 bytes to the packet
2060         if (TimeToSendThisQuestion(q, m->timenow + q->ThisQInterval/2))
2061                 {
2062                 // We forecast: qname (n) type (2) class (2)
2063                 mDNSu32 forecast = (mDNSu32)DomainNameLength(&q->qname) + 4;
2064                 const mDNSu32 slot = HashSlot(&q->qname);
2065                 const CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
2066                 const CacheRecord *rr;
2067                 for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)                         // If we have a resource record in our cache,
2068                         if (rr->resrec.rdlength <= SmallRecordLimit &&                                  // which is small enough to sensibly fit in the packet
2069                                 SameNameRecordAnswersQuestion(&rr->resrec, q) &&                        // which answers our question
2070                                 rr->TimeRcvd + TicksTTL(rr)/2 - m->timenow >= 0 &&                      // and it is less than half-way to expiry
2071                                 rr->NextRequiredQuery - (m->timenow + q->ThisQInterval) > 0)// and we'll ask at least once again before NextRequiredQuery
2072                                 {
2073                                 // We forecast: compressed name (2) type (2) class (2) TTL (4) rdlength (2) rdata (n)
2074                                 forecast += 12 + rr->resrec.rdestimate;
2075                                 if (forecast >= 512) return(mDNSfalse); // If this would add 512 bytes or more to the packet, don't accelerate
2076                                 }
2077                 return(mDNStrue);
2078                 }
2079
2080         return(mDNSfalse);
2081         }
2082
2083 // How Standard Queries are generated:
2084 // 1. The Question Section contains the question
2085 // 2. The Additional Section contains answers we already know, to suppress duplicate responses
2086
2087 // How Probe Queries are generated:
2088 // 1. The Question Section contains queries for the name we intend to use, with QType=ANY because
2089 // if some other host is already using *any* records with this name, we want to know about it.
2090 // 2. The Authority Section contains the proposed values we intend to use for one or more
2091 // of our records with that name (analogous to the Update section of DNS Update packets)
2092 // because if some other host is probing at the same time, we each want to know what the other is
2093 // planning, in order to apply the tie-breaking rule to see who gets to use the name and who doesn't.
2094
2095 mDNSlocal void SendQueries(mDNS *const m)
2096         {
2097         mDNSu32 slot;
2098         CacheGroup *cg;
2099         CacheRecord *cr;
2100         AuthRecord *ar;
2101         int pktcount = 0;
2102         DNSQuestion *q;
2103         // For explanation of maxExistingQuestionInterval logic, see comments for maxExistingAnnounceInterval
2104         mDNSs32 maxExistingQuestionInterval = 0;
2105         const NetworkInterfaceInfo *intf = GetFirstActiveInterface(m->HostInterfaces);
2106         CacheRecord *KnownAnswerList = mDNSNULL;
2107
2108         // 1. If time for a query, work out what we need to do
2109         if (m->timenow - m->NextScheduledQuery >= 0)
2110                 {
2111                 CacheRecord *rr;
2112
2113                 // We're expecting to send a query anyway, so see if any expiring cache records are close enough
2114                 // to their NextRequiredQuery to be worth batching them together with this one
2115                 FORALL_CACHERECORDS(slot, cg, rr)
2116                         if (rr->CRActiveQuestion && rr->UnansweredQueries < MaxUnansweredQueries)
2117                                 if (m->timenow + TicksTTL(rr)/50 - rr->NextRequiredQuery >= 0)
2118                                         {
2119                                         debugf("Sending %d%% cache expiration query for %s", 80 + 5 * rr->UnansweredQueries, CRDisplayString(m, rr));
2120                                         q = rr->CRActiveQuestion;
2121                                         ExpireDupSuppressInfoOnInterface(q->DupSuppress, m->timenow - TicksTTL(rr)/20, rr->resrec.InterfaceID);
2122                                         // For uDNS queries (TargetQID non-zero) we adjust LastQTime,
2123                                         // and bump UnansweredQueries so that we don't spin trying to send the same cache expiration query repeatedly
2124                                         if      (q->Target.type)                        q->SendQNow = mDNSInterfaceMark;        // If targeted query, mark it
2125                                         else if (!mDNSOpaque16IsZero(q->TargetQID))     { q->LastQTime = m->timenow - q->ThisQInterval; rr->UnansweredQueries++; }
2126                                         else if (q->SendQNow == mDNSNULL)               q->SendQNow = rr->resrec.InterfaceID;
2127                                         else if (q->SendQNow != rr->resrec.InterfaceID) q->SendQNow = mDNSInterfaceMark;
2128                                         }
2129
2130                 if (m->SuppressStdPort53Queries && m->timenow - m->SuppressStdPort53Queries >= 0)
2131                         m->SuppressStdPort53Queries = 0; // If suppression time has passed, clear it
2132                         
2133                 // Scan our list of questions to see which:
2134                 //     *WideArea*  queries need to be sent
2135                 //     *unicast*   queries need to be sent
2136                 //     *multicast* queries we're definitely going to send
2137                 if (m->CurrentQuestion)
2138                         LogMsg("SendQueries ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
2139                 m->CurrentQuestion = m->Questions;
2140                 while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
2141                         {
2142                         q = m->CurrentQuestion;
2143                         if (ActiveQuestion(q) && !mDNSOpaque16IsZero(q->TargetQID)) uDNS_CheckCurrentQuestion(m);
2144                         else if (mDNSOpaque16IsZero(q->TargetQID) && q->Target.type && (q->SendQNow || TimeToSendThisQuestion(q, m->timenow)))
2145                                 {
2146                                 mDNSu8       *qptr        = m->omsg.data;
2147                                 const mDNSu8 *const limit = m->omsg.data + sizeof(m->omsg.data);
2148
2149                                 // 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
2150                                 if (!q->LocalSocket) q->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
2151                                 if (q->LocalSocket)
2152                                         {
2153                                         InitializeDNSMessage(&m->omsg.h, q->TargetQID, QueryFlags);
2154                                         qptr = putQuestion(&m->omsg, qptr, limit, &q->qname, q->qtype, q->qclass);
2155                                         mDNSSendDNSMessage(m, &m->omsg, qptr, mDNSInterface_Any, q->LocalSocket, &q->Target, q->TargetPort, mDNSNULL, mDNSNULL);
2156                                         q->ThisQInterval    *= QuestionIntervalStep;
2157                                         }
2158                                 if (q->ThisQInterval > MaxQuestionInterval)
2159                                         q->ThisQInterval = MaxQuestionInterval;
2160                                 q->LastQTime         = m->timenow;
2161                                 q->LastQTxTime       = m->timenow;
2162                                 q->RecentAnswerPkts  = 0;
2163                                 q->SendQNow          = mDNSNULL;
2164                                 q->ExpectUnicastResp = NonZeroTime(m->timenow);
2165                                 }
2166                         else if (mDNSOpaque16IsZero(q->TargetQID) && !q->Target.type && TimeToSendThisQuestion(q, m->timenow))
2167                                 {
2168                                 //LogInfo("Time to send %##s (%s) %d", q->qname.c, DNSTypeName(q->qtype), m->timenow - (q->LastQTime + q->ThisQInterval));
2169                                 q->SendQNow = mDNSInterfaceMark;                // Mark this question for sending on all interfaces
2170                                 if (maxExistingQuestionInterval < q->ThisQInterval)
2171                                         maxExistingQuestionInterval = q->ThisQInterval;
2172                                 }
2173                         // If m->CurrentQuestion wasn't modified out from under us, advance it now
2174                         // We can't do this at the start of the loop because uDNS_CheckCurrentQuestion() depends on having
2175                         // m->CurrentQuestion point to the right question
2176                         if (q == m->CurrentQuestion) m->CurrentQuestion = m->CurrentQuestion->next;
2177                         }
2178                 m->CurrentQuestion = mDNSNULL;
2179
2180                 // Scan our list of questions
2181                 // (a) to see if there are any more that are worth accelerating, and
2182                 // (b) to update the state variables for *all* the questions we're going to send
2183                 // Note: Don't set NextScheduledQuery until here, because uDNS_CheckCurrentQuestion in the loop above can add new questions to the list,
2184                 // which causes NextScheduledQuery to get (incorrectly) set to m->timenow. Setting it here is the right place, because the very
2185                 // 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.
2186                 m->NextScheduledQuery = m->timenow + 0x78000000;
2187                 for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
2188                         {
2189                         if (mDNSOpaque16IsZero(q->TargetQID) && (q->SendQNow ||
2190                                 (!q->Target.type && ActiveQuestion(q) && q->ThisQInterval <= maxExistingQuestionInterval && AccelerateThisQuery(m,q))))
2191                                 {
2192                                 // If at least halfway to next query time, advance to next interval
2193                                 // If less than halfway to next query time, then
2194                                 // treat this as logically a repeat of the last transmission, without advancing the interval
2195                                 if (m->timenow - (q->LastQTime + q->ThisQInterval/2) >= 0)
2196                                         {
2197                                         //LogInfo("Accelerating %##s (%s) %d", q->qname.c, DNSTypeName(q->qtype), m->timenow - (q->LastQTime + q->ThisQInterval));
2198                                         q->SendQNow = mDNSInterfaceMark;        // Mark this question for sending on all interfaces
2199                                         debugf("SendQueries: %##s (%s) next interval %d seconds RequestUnicast = %d",
2200                                                 q->qname.c, DNSTypeName(q->qtype), q->ThisQInterval / InitialQuestionInterval, q->RequestUnicast);
2201                                         q->ThisQInterval *= QuestionIntervalStep;
2202                                         if (q->ThisQInterval > MaxQuestionInterval)
2203                                                 q->ThisQInterval = MaxQuestionInterval;
2204                                         else if (q->CurrentAnswers == 0 && q->ThisQInterval == InitialQuestionInterval * QuestionIntervalStep3 && !q->RequestUnicast &&
2205                                                         !(RRTypeIsAddressType(q->qtype) && CacheHasAddressTypeForName(m, &q->qname, q->qnamehash)))
2206                                                 {
2207                                                 // Generally don't need to log this.
2208                                                 // It's not especially noteworthy if a query finds no results -- this usually happens for domain
2209                                                 // enumeration queries in the LL subdomain (e.g. "db._dns-sd._udp.0.0.254.169.in-addr.arpa")
2210                                                 // and when there simply happen to be no instances of the service the client is looking
2211                                                 // for (e.g. iTunes is set to look for RAOP devices, and the current network has none).
2212                                                 debugf("SendQueries: Zero current answers for %##s (%s); will reconfirm antecedents",
2213                                                         q->qname.c, DNSTypeName(q->qtype));
2214                                                 // Sending third query, and no answers yet; time to begin doubting the source
2215                                                 ReconfirmAntecedents(m, &q->qname, q->qnamehash, 0);
2216                                                 }
2217                                         }
2218
2219                                 // Mark for sending. (If no active interfaces, then don't even try.)
2220                                 q->SendOnAll = (q->SendQNow == mDNSInterfaceMark);
2221                                 if (q->SendOnAll)
2222                                         {
2223                                         q->SendQNow  = !intf ? mDNSNULL : (q->InterfaceID) ? q->InterfaceID : intf->InterfaceID;
2224                                         q->LastQTime = m->timenow;
2225                                         }
2226
2227                                 // If we recorded a duplicate suppression for this question less than half an interval ago,
2228                                 // then we consider it recent enough that we don't need to do an identical query ourselves.
2229                                 ExpireDupSuppressInfo(q->DupSuppress, m->timenow - q->ThisQInterval/2);
2230
2231                                 q->LastQTxTime      = m->timenow;
2232                                 q->RecentAnswerPkts = 0;
2233                                 if (q->RequestUnicast) q->RequestUnicast--;
2234                                 }
2235                         // For all questions (not just the ones we're sending) check what the next scheduled event will be
2236                         SetNextQueryTime(m,q);
2237                         }
2238                 }
2239
2240         // 2. Scan our authoritative RR list to see what probes we might need to send
2241         if (m->timenow - m->NextScheduledProbe >= 0)
2242                 {
2243                 m->NextScheduledProbe = m->timenow + 0x78000000;
2244
2245                 if (m->CurrentRecord)
2246                         LogMsg("SendQueries ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
2247                 m->CurrentRecord = m->ResourceRecords;
2248                 while (m->CurrentRecord)
2249                         {
2250                         AuthRecord *rr = m->CurrentRecord;
2251                         m->CurrentRecord = rr->next;
2252                         if (!AuthRecord_uDNS(rr) && rr->resrec.RecordType == kDNSRecordTypeUnique)      // For all records that are still probing...
2253                                 {
2254                                 // 1. If it's not reached its probe time, just make sure we update m->NextScheduledProbe correctly
2255                                 if (m->timenow - (rr->LastAPTime + rr->ThisAPInterval) < 0)
2256                                         {
2257                                         SetNextAnnounceProbeTime(m, rr);
2258                                         }
2259                                 // 2. else, if it has reached its probe time, mark it for sending and then update m->NextScheduledProbe correctly
2260                                 else if (rr->ProbeCount)
2261                                         {
2262                                         if (rr->AddressProxy.type == mDNSAddrType_IPv4)
2263                                                 {
2264                                                 LogSPS("SendQueries ARP Probe %d %s %s", rr->ProbeCount, InterfaceNameForID(m, rr->resrec.InterfaceID), ARDisplayString(m,rr));
2265                                                 SendARP(m, 1, rr, &zerov4Addr, &zeroEthAddr, &rr->AddressProxy.ip.v4, &rr->WakeUp.IMAC);
2266                                                 }
2267                                         else if (rr->AddressProxy.type == mDNSAddrType_IPv6)
2268                                                 {
2269                                                 LogSPS("SendQueries NDP Probe %d %s", rr->ProbeCount, ARDisplayString(m,rr));
2270                                                 SendNDP(m, 0x87, 0, rr, &zerov6Addr, mDNSNULL, &rr->AddressProxy.ip.v6, &rr->WakeUp.IMAC);
2271                                                 }
2272                                         // Mark for sending. (If no active interfaces, then don't even try.)
2273                                         rr->SendRNow   = (!intf || rr->WakeUp.HMAC.l[0]) ? mDNSNULL : rr->resrec.InterfaceID ? rr->resrec.InterfaceID : intf->InterfaceID;
2274                                         rr->LastAPTime = m->timenow;
2275                                         // When we have a late conflict that resets a record to probing state we use a special marker value greater
2276                                         // than DefaultProbeCountForTypeUnique. Here we detect that state and reset rr->ProbeCount back to the right value.
2277                                         if (rr->ProbeCount > DefaultProbeCountForTypeUnique)
2278                                                 rr->ProbeCount = DefaultProbeCountForTypeUnique;
2279                                         rr->ProbeCount--;
2280                                         SetNextAnnounceProbeTime(m, rr);
2281                                         if (rr->ProbeCount == 0)
2282                                                 {
2283                                                 // If this is the last probe for this record, then see if we have any matching records
2284                                                 // on our duplicate list which should similarly have their ProbeCount cleared to zero...
2285                                                 AuthRecord *r2;
2286                                                 for (r2 = m->DuplicateRecords; r2; r2=r2->next)
2287                                                         if (r2->resrec.RecordType == kDNSRecordTypeUnique && RecordIsLocalDuplicate(r2, rr))
2288                                                                 r2->ProbeCount = 0;
2289                                                 // ... then acknowledge this record to the client.
2290                                                 // We do this optimistically, just as we're about to send the third probe.
2291                                                 // This helps clients that both advertise and browse, and want to filter themselves
2292                                                 // from the browse results list, because it helps ensure that the registration
2293                                                 // confirmation will be delivered 1/4 second *before* the browse "add" event.
2294                                                 // A potential downside is that we could deliver a registration confirmation and then find out
2295                                                 // moments later that there's a name conflict, but applications have to be prepared to handle
2296                                                 // late conflicts anyway (e.g. on connection of network cable, etc.), so this is nothing new.
2297                                                 if (!rr->Acknowledged) AcknowledgeRecord(m, rr);
2298                                                 }
2299                                         }
2300                                 // else, if it has now finished probing, move it to state Verified,
2301                                 // and update m->NextScheduledResponse so it will be announced
2302                                 else
2303                                         {
2304                                         if (!rr->Acknowledged) AcknowledgeRecord(m, rr);        // Defensive, just in case it got missed somehow
2305                                         rr->resrec.RecordType     = kDNSRecordTypeVerified;
2306                                         rr->ThisAPInterval = DefaultAnnounceIntervalForTypeUnique;
2307                                         rr->LastAPTime     = m->timenow - DefaultAnnounceIntervalForTypeUnique;
2308                                         SetNextAnnounceProbeTime(m, rr);
2309                                         }
2310                                 }
2311                         }
2312                 m->CurrentRecord = m->DuplicateRecords;
2313                 while (m->CurrentRecord)
2314                         {
2315                         AuthRecord *rr = m->CurrentRecord;
2316                         m->CurrentRecord = rr->next;
2317                         if (rr->resrec.RecordType == kDNSRecordTypeUnique && rr->ProbeCount == 0 && !rr->Acknowledged)
2318                                 AcknowledgeRecord(m, rr);
2319                         }
2320                 }
2321
2322         // 3. Now we know which queries and probes we're sending,
2323         // go through our interface list sending the appropriate queries on each interface
2324         while (intf)
2325                 {
2326                 const int OwnerRecordSpace = (m->AnnounceOwner && intf->MAC.l[0]) ? DNSOpt_Header_Space + DNSOpt_Owner_Space(&m->PrimaryMAC, &intf->MAC) : 0;
2327                 AuthRecord *rr;
2328                 mDNSu8 *queryptr = m->omsg.data;
2329                 InitializeDNSMessage(&m->omsg.h, zeroID, QueryFlags);
2330                 if (KnownAnswerList) verbosedebugf("SendQueries:   KnownAnswerList set... Will continue from previous packet");
2331                 if (!KnownAnswerList)
2332                         {
2333                         // Start a new known-answer list
2334                         CacheRecord **kalistptr = &KnownAnswerList;
2335                         mDNSu32 answerforecast = OwnerRecordSpace;              // We start by assuming we'll need at least enough space to put the Owner Option
2336                         
2337                         // Put query questions in this packet
2338                         for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
2339                                 {
2340                                 if (mDNSOpaque16IsZero(q->TargetQID) && (q->SendQNow == intf->InterfaceID))
2341                                         {
2342                                         debugf("SendQueries: %s question for %##s (%s) at %d forecast total %d",
2343                                                 SuppressOnThisInterface(q->DupSuppress, intf) ? "Suppressing" : "Putting    ",
2344                                                 q->qname.c, DNSTypeName(q->qtype), queryptr - m->omsg.data, queryptr + answerforecast - m->omsg.data);
2345
2346                                         // If we're suppressing this question, or we successfully put it, update its SendQNow state
2347                                         if (SuppressOnThisInterface(q->DupSuppress, intf) ||
2348                                                 BuildQuestion(m, &m->omsg, &queryptr, q, &kalistptr, &answerforecast))
2349                                                         q->SendQNow = (q->InterfaceID || !q->SendOnAll) ? mDNSNULL : GetNextActiveInterfaceID(intf);
2350                                         }
2351                                 }
2352
2353                         // Put probe questions in this packet
2354                         for (rr = m->ResourceRecords; rr; rr=rr->next)
2355                                 if (rr->SendRNow == intf->InterfaceID)
2356                                         {
2357                                         mDNSBool ucast = (rr->ProbeCount >= DefaultProbeCountForTypeUnique-1) && m->CanReceiveUnicastOn5353;
2358                                         mDNSu16 ucbit = (mDNSu16)(ucast ? kDNSQClass_UnicastResponse : 0);
2359                                         const mDNSu8 *const limit = m->omsg.data + (m->omsg.h.numQuestions ? NormalMaxDNSMessageData : AbsoluteMaxDNSMessageData);
2360                                         // We forecast: compressed name (2) type (2) class (2) TTL (4) rdlength (2) rdata (n)
2361                                         mDNSu32 forecast = answerforecast + 12 + rr->resrec.rdestimate;
2362                                         mDNSu8 *newptr = putQuestion(&m->omsg, queryptr, limit - forecast, rr->resrec.name, kDNSQType_ANY, (mDNSu16)(rr->resrec.rrclass | ucbit));
2363                                         if (newptr)
2364                                                 {
2365                                                 queryptr       = newptr;
2366                                                 answerforecast = forecast;
2367                                                 rr->SendRNow = (rr->resrec.InterfaceID) ? mDNSNULL : GetNextActiveInterfaceID(intf);
2368                                                 rr->IncludeInProbe = mDNStrue;
2369                                                 verbosedebugf("SendQueries:   Put Question %##s (%s) probecount %d",
2370                                                         rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype), rr->ProbeCount);
2371                                                 }
2372                                         }
2373                         }
2374
2375                 // Put our known answer list (either new one from this question or questions, or remainder of old one from last time)
2376                 while (KnownAnswerList)
2377                         {
2378                         CacheRecord *ka = KnownAnswerList;
2379                         mDNSu32 SecsSinceRcvd = ((mDNSu32)(m->timenow - ka->TimeRcvd)) / mDNSPlatformOneSecond;
2380                         mDNSu8 *newptr = PutResourceRecordTTLWithLimit(&m->omsg, queryptr, &m->omsg.h.numAnswers,
2381                                 &ka->resrec, ka->resrec.rroriginalttl - SecsSinceRcvd, m->omsg.data + NormalMaxDNSMessageData - OwnerRecordSpace);
2382                         if (newptr)
2383                                 {
2384                                 verbosedebugf("SendQueries:   Put %##s (%s) at %d - %d",
2385                                         ka->resrec.name->c, DNSTypeName(ka->resrec.rrtype), queryptr - m->omsg.data, newptr - m->omsg.data);
2386                                 queryptr = newptr;
2387                                 KnownAnswerList = ka->NextInKAList;
2388                                 ka->NextInKAList = mDNSNULL;
2389                                 }
2390                         else
2391                                 {
2392                                 // If we ran out of space and we have more than one question in the packet, that's an error --
2393                                 // we shouldn't have put more than one question if there was a risk of us running out of space.
2394                                 if (m->omsg.h.numQuestions > 1)
2395                                         LogMsg("SendQueries:   Put %d answers; No more space for known answers", m->omsg.h.numAnswers);
2396                                 m->omsg.h.flags.b[0] |= kDNSFlag0_TC;
2397                                 break;
2398                                 }
2399                         }
2400
2401                 for (rr = m->ResourceRecords; rr; rr=rr->next)
2402                         if (rr->IncludeInProbe)
2403                                 {
2404                                 mDNSu8 *newptr = PutResourceRecord(&m->omsg, queryptr, &m->omsg.h.numAuthorities, &rr->resrec);
2405                                 rr->IncludeInProbe = mDNSfalse;
2406                                 if (newptr) queryptr = newptr;
2407                                 else LogMsg("SendQueries:   How did we fail to have space for the Update record %s", ARDisplayString(m,rr));
2408                                 }
2409
2410                 if (queryptr > m->omsg.data)
2411                         {
2412                         if (OwnerRecordSpace)
2413                                 {
2414                                 AuthRecord opt;
2415                                 mDNS_SetupResourceRecord(&opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, mDNSNULL, mDNSNULL);
2416                                 opt.resrec.rrclass    = NormalMaxDNSMessageData;
2417                                 opt.resrec.rdlength   = sizeof(rdataOPT);       // One option in this OPT record
2418                                 opt.resrec.rdestimate = sizeof(rdataOPT);
2419                                 SetupOwnerOpt(m, intf, &opt.resrec.rdata->u.opt[0]);
2420                                 LogSPS("SendQueries putting %s", ARDisplayString(m, &opt));
2421                                 queryptr = PutResourceRecordTTLWithLimit(&m->omsg, queryptr, &m->omsg.h.numAdditionals,
2422                                         &opt.resrec, opt.resrec.rroriginalttl, m->omsg.data + AbsoluteMaxDNSMessageData);
2423                                 if (!queryptr)
2424                                         LogMsg("SendQueries: How did we fail to have space for the OPT record (%d/%d/%d/%d) %s",
2425                                                 m->omsg.h.numQuestions, m->omsg.h.numAnswers, m->omsg.h.numAuthorities, m->omsg.h.numAdditionals, ARDisplayString(m, &opt));
2426                                 if (queryptr > m->omsg.data + NormalMaxDNSMessageData)
2427                                         if (m->omsg.h.numQuestions != 1 || m->omsg.h.numAnswers != 0 || m->omsg.h.numAuthorities != 1 || m->omsg.h.numAdditionals != 1)
2428                                                 LogMsg("SendQueries: Why did we generate oversized packet with OPT record %p %p %p (%d/%d/%d/%d) %s",
2429                                                         m->omsg.data, m->omsg.data + NormalMaxDNSMessageData, queryptr,
2430                                                         m->omsg.h.numQuestions, m->omsg.h.numAnswers, m->omsg.h.numAuthorities, m->omsg.h.numAdditionals, ARDisplayString(m, &opt));
2431                                 }
2432
2433                         if ((m->omsg.h.flags.b[0] & kDNSFlag0_TC) && m->omsg.h.numQuestions > 1)
2434                                 LogMsg("SendQueries: Should not have more than one question (%d) in a truncated packet", m->omsg.h.numQuestions);
2435                         debugf("SendQueries:   Sending %d Question%s %d Answer%s %d Update%s on %p",
2436                                 m->omsg.h.numQuestions,   m->omsg.h.numQuestions   == 1 ? "" : "s",
2437                                 m->omsg.h.numAnswers,     m->omsg.h.numAnswers     == 1 ? "" : "s",
2438                                 m->omsg.h.numAuthorities, m->omsg.h.numAuthorities == 1 ? "" : "s", intf->InterfaceID);
2439                         if (intf->IPv4Available) mDNSSendDNSMessage(m, &m->omsg, queryptr, intf->InterfaceID, mDNSNULL, &AllDNSLinkGroup_v4, MulticastDNSPort, mDNSNULL, mDNSNULL);
2440                         if (intf->IPv6Available) mDNSSendDNSMessage(m, &m->omsg, queryptr, intf->InterfaceID, mDNSNULL, &AllDNSLinkGroup_v6, MulticastDNSPort, mDNSNULL, mDNSNULL);
2441                         if (!m->SuppressSending) m->SuppressSending = NonZeroTime(m->timenow + (mDNSPlatformOneSecond+9)/10);
2442                         if (++pktcount >= 1000)
2443                                 { LogMsg("SendQueries exceeded loop limit %d: giving up", pktcount); break; }
2444                         // There might be more records left in the known answer list, or more questions to send
2445                         // on this interface, so go around one more time and try again.
2446                         }
2447                 else    // Nothing more to send on this interface; go to next
2448                         {
2449                         const NetworkInterfaceInfo *next = GetFirstActiveInterface(intf->next);
2450                         #if MDNS_DEBUGMSGS && 0
2451                         const char *const msg = next ? "SendQueries:   Nothing more on %p; moving to %p" : "SendQueries:   Nothing more on %p";
2452                         debugf(msg, intf, next);
2453                         #endif
2454                         intf = next;
2455                         }
2456                 }
2457
2458         // 4. Final housekeeping
2459         
2460         // 4a. Debugging check: Make sure we announced all our records
2461         for (ar = m->ResourceRecords; ar; ar=ar->next)
2462                 if (ar->SendRNow)
2463                         {
2464                         if (ar->resrec.InterfaceID != mDNSInterface_LocalOnly)
2465                                 LogMsg("SendQueries: No active interface to send: %s", ARDisplayString(m, ar));
2466                         ar->SendRNow = mDNSNULL;
2467                         }
2468
2469         // 4b. When we have lingering cache records that we're keeping around for a few seconds in the hope
2470         // that their interface which went away might come back again, the logic will want to send queries
2471         // for those records, but we can't because their interface isn't here any more, so to keep the
2472         // state machine ticking over we just pretend we did so.
2473         // If the interface does not come back in time, the cache record will expire naturally
2474         FORALL_CACHERECORDS(slot, cg, cr)
2475                 if (cr->CRActiveQuestion && cr->UnansweredQueries < MaxUnansweredQueries && m->timenow - cr->NextRequiredQuery >= 0)
2476                         {
2477                         cr->UnansweredQueries++;
2478                         cr->CRActiveQuestion->SendQNow = mDNSNULL;
2479                         SetNextCacheCheckTime(m, cr);
2480                         }
2481
2482         // 4c. Debugging check: Make sure we sent all our planned questions
2483         // Do this AFTER the lingering cache records check above, because that will prevent spurious warnings for questions
2484         // we legitimately couldn't send because the interface is no longer available
2485         for (q = m->Questions; q; q=q->next)
2486                 if (q->SendQNow)
2487                         {
2488                         LogMsg("SendQueries: No active interface to send: %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
2489                         q->SendQNow = mDNSNULL;
2490                         }
2491         }
2492
2493 mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAddr *EthAddr, mDNSOpaque48 *password)
2494         {
2495         int i, j;
2496         mDNSu8 *ptr = m->omsg.data;
2497
2498         if (!InterfaceID) { LogMsg("SendWakeup: No InterfaceID specified"); return; }
2499
2500         // 0x00 Destination address
2501         for (i=0; i<6; i++) *ptr++ = EthAddr->b[i];
2502
2503         // 0x06 Source address (Note: We just use zero. Unless we set the BIOCSHDRCMPLT option, BPF will fill in real interface address)
2504         for (i=0; i<6; i++) *ptr++ = 0x0;
2505
2506         // 0x0C Ethertype (0x0842)
2507         *ptr++ = 0x08;
2508         *ptr++ = 0x42;
2509
2510         // 0x0E Wakeup sync sequence
2511         for (i=0; i<6; i++) *ptr++ = 0xFF;
2512
2513         // 0x14 Wakeup data
2514         for (j=0; j<16; j++) for (i=0; i<6; i++) *ptr++ = EthAddr->b[i];
2515
2516         // 0x74 Password
2517         for (i=0; i<6; i++) *ptr++ = password->b[i];
2518
2519         mDNSPlatformSendRawPacket(m->omsg.data, ptr, InterfaceID);
2520
2521         // For Ethernet switches that don't flood-foward packets with unknown unicast destination MAC addresses,
2522         // broadcast is the only reliable way to get a wakeup packet to the intended target machine.
2523         // For 802.11 WPA networks, where a sleeping target machine may have missed a broadcast/multicast
2524         // key rotation, unicast is the only way to get a wakeup packet to the intended target machine.
2525         // So, we send one of each, unicast first, then broadcast second.
2526         for (i=0; i<6; i++) m->omsg.data[i] = 0xFF;
2527         mDNSPlatformSendRawPacket(m->omsg.data, ptr, InterfaceID);
2528         }
2529
2530 // ***************************************************************************
2531 #if COMPILER_LIKES_PRAGMA_MARK
2532 #pragma mark -
2533 #pragma mark - RR List Management & Task Management
2534 #endif
2535
2536 // Note: AnswerCurrentQuestionWithResourceRecord can call a user callback, which may change the record list and/or question list.
2537 // Any code walking either list must use the m->CurrentQuestion (and possibly m->CurrentRecord) mechanism to protect against this.
2538 // In fact, to enforce this, the routine will *only* answer the question currently pointed to by m->CurrentQuestion,
2539 // which will be auto-advanced (possibly to NULL) if the client callback cancels the question.
2540 mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheRecord *const rr, const QC_result AddRecord)
2541         {
2542         DNSQuestion *const q = m->CurrentQuestion;
2543         mDNSBool followcname = rr->resrec.RecordType != kDNSRecordTypePacketNegative && AddRecord &&
2544                                                         rr->resrec.rrtype == kDNSType_CNAME && q->qtype != kDNSType_CNAME;
2545         verbosedebugf("AnswerCurrentQuestionWithResourceRecord:%4lu %s TTL %d %s",
2546                 q->CurrentAnswers, AddRecord ? "Add" : "Rmv", rr->resrec.rroriginalttl, CRDisplayString(m, rr));
2547
2548         // Note: Use caution here. In the case of records with rr->DelayDelivery set, AnswerCurrentQuestionWithResourceRecord(... mDNStrue)
2549         // may be called twice, once when the record is received, and again when it's time to notify local clients.
2550         // If any counters or similar are added here, care must be taken to ensure that they are not double-incremented by this.
2551
2552         rr->LastUsed = m->timenow;
2553         if (AddRecord == QC_add && !q->DuplicateOf && rr->CRActiveQuestion != q)
2554                 {
2555                 if (!rr->CRActiveQuestion) m->rrcache_active++; // If not previously active, increment rrcache_active count
2556                 debugf("AnswerCurrentQuestionWithResourceRecord: Updating CRActiveQuestion to %p for cache record %s", q, CRDisplayString(m,rr));
2557                 rr->CRActiveQuestion = q;                                               // We know q is non-null
2558                 SetNextCacheCheckTime(m, rr);
2559                 }
2560
2561         // If this is:
2562         // (a) a no-cache add, where we've already done at least one 'QM' query, or
2563         // (b) a normal add, where we have at least one unique-type answer,
2564         // then there's no need to keep polling the network.
2565         // (If we have an answer in the cache, then we'll automatically ask again in time to stop it expiring.)
2566         // We do this for mDNS questions and uDNS one-shot questions, but not for
2567         // uDNS LongLived questions, because that would mess up our LLQ lease renewal timing.
2568         if ((AddRecord == QC_addnocache && !q->RequestUnicast) ||
2569                 (AddRecord == QC_add && (q->ExpectUnique || (rr->resrec.RecordType & kDNSRecordTypePacketUniqueMask))))
2570                 if (ActiveQuestion(q) && (mDNSOpaque16IsZero(q->TargetQID) || !q->LongLived))
2571                         {
2572                         q->LastQTime        = m->timenow;
2573                         q->LastQTxTime      = m->timenow;
2574                         q->RecentAnswerPkts = 0;
2575                         q->ThisQInterval    = MaxQuestionInterval;
2576                         q->RequestUnicast   = mDNSfalse;
2577                         debugf("AnswerCurrentQuestionWithResourceRecord: Set MaxQuestionInterval for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
2578                         }
2579
2580         if (rr->DelayDelivery) return;          // We'll come back later when CacheRecordDeferredAdd() calls us
2581
2582         // Only deliver negative answers if client has explicitly requested them
2583         if (rr->resrec.RecordType == kDNSRecordTypePacketNegative || (q->qtype != kDNSType_NSEC && RRAssertsNonexistence(&rr->resrec, q->qtype)))
2584                 if (!AddRecord || !q->ReturnIntermed) return;
2585
2586         // For CNAME results to non-CNAME questions, only inform the client if they explicitly requested that
2587         if (q->QuestionCallback && !q->NoAnswer && (!followcname || q->ReturnIntermed))
2588                 {
2589                 mDNS_DropLockBeforeCallback();          // Allow client (and us) to legally make mDNS API calls
2590                 if (q->qtype != kDNSType_NSEC && RRAssertsNonexistence(&rr->resrec, q->qtype))
2591                         {
2592                         CacheRecord neg;
2593                         MakeNegativeCacheRecord(m, &neg, &q->qname, q->qnamehash, q->qtype, q->qclass, 1, rr->resrec.InterfaceID, q->qDNSServer);
2594                         q->QuestionCallback(m, q, &neg.resrec, AddRecord);
2595                         }
2596                 else
2597                         q->QuestionCallback(m, q, &rr->resrec, AddRecord);
2598                 mDNS_ReclaimLockAfterCallback();        // Decrement mDNS_reentrancy to block mDNS API calls again
2599                 }
2600         // Note: Proceed with caution here because client callback function is allowed to do anything,
2601         // including starting/stopping queries, registering/deregistering records, etc.
2602
2603         if (followcname && m->CurrentQuestion == q && q->CNAMEReferrals < 10)
2604                 {
2605                 const mDNSu32 c = q->CNAMEReferrals + 1;
2606                 // Right now we just stop and re-use the existing query. If we really wanted to be 100% perfect,
2607                 // and track CNAMEs coming and going, we should really create a subordinate query here,
2608                 // which we would subsequently cancel and retract if the CNAME referral record were removed.
2609                 // In reality this is such a corner case we'll ignore it until someone actually needs it.
2610                 LogInfo("AnswerCurrentQuestionWithResourceRecord: following CNAME referral for %s", CRDisplayString(m, rr));
2611                 
2612                 // If this query is a duplicate of another query, UpdateQuestionDuplicates called from
2613                 // mDNS_StopQuery_internal copies the value of CNAMEReferrals from this query to the other
2614                 // query on the Questions list. By setting the new value before calling mDNS_StopQuery_internal,
2615                 // we ensure that the duplicate question gets a hgigher value and eventually the check for 10 above
2616                 // would be true. Otherwise, the two queries would end up as active questions
2617                 // sending mDNSResponder in an infinite loop e.g., Two queries starting off unique but receives
2618                 // a CNAME response that refers to itself (test IN CNAME test) which makes it a duplicate of
2619                 // one another. This fix now will make sure that stop at the 10th iteration. 
2620                 //
2621                 // Though CNAME records that refer to itself are not added anymore in mDNSCoreReceiveResponse, this fix is
2622                 // still needed to catch the cases where the CNAME referral spans across multiple records with a potential
2623                 // cycle in it which in turn can make multiple queries duplicate of each other
2624                 
2625                 q->CNAMEReferrals = c;                  // Need to set new CNAMEReferrals count *before* stopping the query, in case
2626                                                                                 // stopping the query causes the value to be copied to a duplicate question in the list
2627                 mDNS_StopQuery_internal(m, q);                                                          // Stop old query
2628                 AssignDomainName(&q->qname, &rr->resrec.rdata->u.name);         // Update qname
2629                 q->qnamehash = DomainNameHashValue(&q->qname);                          // and namehash
2630                 mDNS_StartQuery_internal(m, q);                                                         // start new query
2631                 q->CNAMEReferrals = c;                  // Record how many times we've done this
2632                                                                                 // Need to do this *after* mDNS_StartQuery_internal,
2633                                                                                 // because mDNS_StartQuery_internal initializes CNAMEReferrals to zero
2634                 }
2635         }
2636
2637 // New Questions are answered through AnswerNewQuestions. But there may not have been any
2638 // matching cache records for the questions when it is called. There are two possibilities.
2639 //
2640 // 1) There are no cache records
2641 // 2) There are cache records but the DNSServers between question and cache record don't match.
2642 //
2643 // In the case of (1), where there are no cache records and later we add them when we get a response,
2644 // CacheRecordAdd/CacheRecordDeferredAdd will take care of adding the cache and delivering the ADD
2645 // events to the application. If we already have a cache entry, then no ADD events are delivered
2646 // unless the RDATA has changed
2647 //
2648 // In the case of (2) where we had the cache records and did not answer because of the DNSServer mismatch,
2649 // we need to answer them whenever we change the DNSServer.  But we can't do it at the instant the DNSServer
2650 // changes because when we do the callback, the question can get deleted and the calling function would not
2651 // know how to handle it. So, we run this function from mDNS_Execute to handle DNSServer changes on the
2652 // question
2653
2654 mDNSlocal void AnswerQuestionsForDNSServerChanges(mDNS *const m)
2655         {
2656         DNSQuestion *q;
2657         DNSQuestion *qnext;
2658         CacheRecord *rr;
2659         mDNSu32 slot;
2660         CacheGroup *cg;
2661
2662         if (m->CurrentQuestion)
2663                 LogMsg("AnswerQuestionsForDNSServerChanges: ERROR m->CurrentQuestion already set: %##s (%s)",
2664                                 m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
2665
2666         for (q = m->Questions; q && q != m->NewQuestions; q = qnext)
2667                 {
2668                 qnext = q->next;
2669
2670                 // multicast or DNSServers did not change.
2671                 if (mDNSOpaque16IsZero(q->TargetQID)) continue;
2672                 if (!q->deliverAddEvents) continue;
2673
2674                 // We are going to look through the cache for this question since it changed
2675                 // its DNSserver last time. Reset it so that we don't call them again. Calling
2676                 // them again will deliver duplicate events to the application
2677                 q->deliverAddEvents = mDNSfalse;
2678                 m->CurrentQuestion = q;
2679                 slot = HashSlot(&q->qname);
2680                 cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
2681                 for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
2682                         {
2683                         if (SameNameRecordAnswersQuestion(&rr->resrec, q))
2684                                 {
2685                                 LogInfo("AnswerQuestionsForDNSServerChanges: Calling AnswerCurrentQuestionWithResourceRecord for question %##s using resource record %s", q->qname.c, CRDisplayString(m, rr));
2686                                 AnswerCurrentQuestionWithResourceRecord(m, rr, QC_add);
2687                                 if (m->CurrentQuestion != q) break;             // If callback deleted q, then we're finished here
2688                                 }
2689                         }
2690                 }
2691                 m->CurrentQuestion = mDNSNULL;
2692         }
2693
2694 mDNSlocal void CacheRecordDeferredAdd(mDNS *const m, CacheRecord *rr)
2695         {
2696         rr->DelayDelivery = 0;          // Note, only need to call SetNextCacheCheckTime() when DelayDelivery is set, not when it's cleared
2697         if (m->CurrentQuestion)
2698                 LogMsg("CacheRecordDeferredAdd ERROR m->CurrentQuestion already set: %##s (%s)",
2699                         m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
2700         m->CurrentQuestion = m->Questions;
2701         while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
2702                 {
2703                 DNSQuestion *q = m->CurrentQuestion;
2704                 if (ResourceRecordAnswersQuestion(&rr->resrec, q))
2705                         AnswerCurrentQuestionWithResourceRecord(m, rr, QC_add);
2706                 if (m->CurrentQuestion == q)    // If m->CurrentQuestion was not auto-advanced, do it ourselves now
2707                         m->CurrentQuestion = q->next;
2708                 }
2709         m->CurrentQuestion = mDNSNULL;
2710         }
2711
2712 mDNSlocal mDNSs32 CheckForSoonToExpireRecords(mDNS *const m, const domainname *const name, const mDNSu32 namehash, const mDNSu32 slot)
2713         {
2714         const mDNSs32 threshhold = m->timenow + mDNSPlatformOneSecond;  // See if there are any records expiring within one second
2715         const mDNSs32 start      = m->timenow - 0x10000000;
2716         mDNSs32 delay = start;
2717         CacheGroup *cg = CacheGroupForName(m, slot, namehash, name);
2718         const CacheRecord *rr;
2719         for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
2720                 if (threshhold - RRExpireTime(rr) >= 0)         // If we have records about to expire within a second
2721                         if (delay - RRExpireTime(rr) < 0)               // then delay until after they've been deleted
2722                                 delay = RRExpireTime(rr);
2723         if (delay - start > 0) return(NonZeroTime(delay));
2724         else return(0);
2725         }
2726
2727 // CacheRecordAdd is only called from mDNSCoreReceiveResponse, *never* directly as a result of a client API call.
2728 // If new questions are created as a result of invoking client callbacks, they will be added to
2729 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
2730 // rr is a new CacheRecord just received into our cache
2731 // (kDNSRecordTypePacketAns/PacketAnsUnique/PacketAdd/PacketAddUnique).
2732 // Note: CacheRecordAdd calls AnswerCurrentQuestionWithResourceRecord which can call a user callback,
2733 // which may change the record list and/or question list.
2734 // Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
2735 mDNSlocal void CacheRecordAdd(mDNS *const m, CacheRecord *rr)
2736         {
2737         DNSQuestion *q;
2738
2739         // We stop when we get to NewQuestions -- if we increment their CurrentAnswers/LargeAnswers/UniqueAnswers
2740         // counters here we'll end up double-incrementing them when we do it again in AnswerNewQuestion().
2741         for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
2742                 {
2743                 if (ResourceRecordAnswersQuestion(&rr->resrec, q))
2744                         {
2745                         // If this question is one that's actively sending queries, and it's received ten answers within one
2746                         // second of sending the last query packet, then that indicates some radical network topology change,
2747                         // so reset its exponential backoff back to the start. We must be at least at the eight-second interval
2748                         // to do this. If we're at the four-second interval, or less, there's not much benefit accelerating
2749                         // because we will anyway send another query within a few seconds. The first reset query is sent out
2750                         // randomized over the next four seconds to reduce possible synchronization between machines.
2751                         if (q->LastAnswerPktNum != m->PktNum)
2752                                 {
2753                                 q->LastAnswerPktNum = m->PktNum;
2754                                 if (mDNSOpaque16IsZero(q->TargetQID) && ActiveQuestion(q) && ++q->RecentAnswerPkts >= 10 &&
2755                                         q->ThisQInterval > InitialQuestionInterval * QuestionIntervalStep3 && m->timenow - q->LastQTxTime < mDNSPlatformOneSecond)
2756                                         {
2757                                         LogMsg("CacheRecordAdd: %##s (%s) got immediate answer burst (%d); restarting exponential backoff sequence (%d)",
2758                                                 q->qname.c, DNSTypeName(q->qtype), q->RecentAnswerPkts, q->ThisQInterval);
2759                                         q->LastQTime      = m->timenow - InitialQuestionInterval + (mDNSs32)mDNSRandom((mDNSu32)mDNSPlatformOneSecond*4);
2760                                         q->ThisQInterval  = InitialQuestionInterval;
2761                                         SetNextQueryTime(m,q);
2762                                         }
2763                                 }
2764                         verbosedebugf("CacheRecordAdd %p %##s (%s) %lu",
2765                                 rr, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype), rr->resrec.rroriginalttl);
2766                         q->CurrentAnswers++;
2767                         q->unansweredQueries = 0;
2768                         if (rr->resrec.rdlength > SmallRecordLimit) q->LargeAnswers++;
2769                         if (rr->resrec.RecordType & kDNSRecordTypePacketUniqueMask) q->UniqueAnswers++;
2770                         if (q->CurrentAnswers > 4000)
2771                                 {
2772                                 static int msgcount = 0;
2773                                 if (msgcount++ < 10)
2774                                         LogMsg("CacheRecordAdd: %##s (%s) has %d answers; shedding records to resist DOS attack",
2775                                                 q->qname.c, DNSTypeName(q->qtype), q->CurrentAnswers);
2776                                 rr->resrec.rroriginalttl = 0;
2777                                 rr->UnansweredQueries = MaxUnansweredQueries;
2778                                 }
2779                         }
2780                 }
2781
2782         if (!rr->DelayDelivery)
2783                 {
2784                 if (m->CurrentQuestion)
2785                         LogMsg("CacheRecordAdd ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
2786                 m->CurrentQuestion = m->Questions;
2787                 while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
2788                         {
2789                         q = m->CurrentQuestion;
2790                         if (ResourceRecordAnswersQuestion(&rr->resrec, q))
2791                                 AnswerCurrentQuestionWithResourceRecord(m, rr, QC_add);
2792                         if (m->CurrentQuestion == q)    // If m->CurrentQuestion was not auto-advanced, do it ourselves now
2793                                 m->CurrentQuestion = q->next;
2794                         }
2795                 m->CurrentQuestion = mDNSNULL;
2796                 }
2797
2798         SetNextCacheCheckTime(m, rr);
2799         }
2800
2801 // NoCacheAnswer is only called from mDNSCoreReceiveResponse, *never* directly as a result of a client API call.
2802 // If new questions are created as a result of invoking client callbacks, they will be added to
2803 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
2804 // rr is a new CacheRecord just received from the wire (kDNSRecordTypePacketAns/AnsUnique/Add/AddUnique)
2805 // but we don't have any place to cache it. We'll deliver question 'add' events now, but we won't have any
2806 // way to deliver 'remove' events in future, nor will we be able to include this in known-answer lists,
2807 // so we immediately bump ThisQInterval up to MaxQuestionInterval to avoid pounding the network.
2808 // Note: NoCacheAnswer calls AnswerCurrentQuestionWithResourceRecord which can call a user callback,
2809 // which may change the record list and/or question list.
2810 // Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
2811 mDNSlocal void NoCacheAnswer(mDNS *const m, CacheRecord *rr)
2812         {
2813         LogMsg("No cache space: Delivering non-cached result for %##s", m->rec.r.resrec.name->c);
2814         if (m->CurrentQuestion)
2815                 LogMsg("NoCacheAnswer ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
2816         m->CurrentQuestion = m->Questions;
2817         // We do this for *all* questions, not stopping when we get to m->NewQuestions,
2818         // since we're not caching the record and we'll get no opportunity to do this later
2819         while (m->CurrentQuestion)
2820                 {
2821                 DNSQuestion *q = m->CurrentQuestion;
2822                 if (ResourceRecordAnswersQuestion(&rr->resrec, q))
2823                         AnswerCurrentQuestionWithResourceRecord(m, rr, QC_addnocache);  // QC_addnocache means "don't expect remove events for this"
2824                 if (m->CurrentQuestion == q)    // If m->CurrentQuestion was not auto-advanced, do it ourselves now
2825                         m->CurrentQuestion = q->next;
2826                 }
2827         m->CurrentQuestion = mDNSNULL;
2828         }
2829
2830 // CacheRecordRmv is only called from CheckCacheExpiration, which is called from mDNS_Execute.
2831 // Note that CacheRecordRmv is *only* called for records that are referenced by at least one active question.
2832 // If new questions are created as a result of invoking client callbacks, they will be added to
2833 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
2834 // rr is an existing cache CacheRecord that just expired and is being deleted
2835 // (kDNSRecordTypePacketAns/PacketAnsUnique/PacketAdd/PacketAddUnique).
2836 // Note: CacheRecordRmv calls AnswerCurrentQuestionWithResourceRecord which can call a user callback,
2837 // which may change the record list and/or question list.
2838 // Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
2839 mDNSlocal void CacheRecordRmv(mDNS *const m, CacheRecord *rr)
2840         {
2841         if (m->CurrentQuestion)
2842                 LogMsg("CacheRecordRmv ERROR m->CurrentQuestion already set: %##s (%s)",
2843                         m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
2844         m->CurrentQuestion = m->Questions;
2845
2846         // We stop when we get to NewQuestions -- for new questions their CurrentAnswers/LargeAnswers/UniqueAnswers counters
2847         // will all still be zero because we haven't yet gone through the cache counting how many answers we have for them.
2848         while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
2849                 {
2850                 DNSQuestion *q = m->CurrentQuestion;
2851                 if (ResourceRecordAnswersQuestion(&rr->resrec, q))
2852                         {
2853                         verbosedebugf("CacheRecordRmv %p %s", rr, CRDisplayString(m, rr));
2854                         q->FlappingInterface1 = mDNSNULL;
2855                         q->FlappingInterface2 = mDNSNULL;
2856                         if (q->CurrentAnswers == 0)
2857                                 LogMsg("CacheRecordRmv ERROR: How can CurrentAnswers already be zero for %p %##s (%s)?",
2858                                         q, q->qname.c, DNSTypeName(q->qtype));
2859                         else
2860                                 {
2861                                 q->CurrentAnswers--;
2862                                 if (rr->resrec.rdlength > SmallRecordLimit) q->LargeAnswers--;
2863                                 if (rr->resrec.RecordType & kDNSRecordTypePacketUniqueMask) q->UniqueAnswers--;
2864                                 }
2865                         if (rr->resrec.rdata->MaxRDLength) // Never generate "remove" events for negative results
2866                                 {
2867                                 if (q->CurrentAnswers == 0)
2868                                         {
2869                                         LogInfo("CacheRecordRmv: Last answer for %##s (%s) expired from cache; will reconfirm antecedents",
2870                                                 q->qname.c, DNSTypeName(q->qtype));
2871                                         ReconfirmAntecedents(m, &q->qname, q->qnamehash, 0);
2872                                         }
2873                                 AnswerCurrentQuestionWithResourceRecord(m, rr, QC_rmv);
2874                                 }
2875                         }
2876                 if (m->CurrentQuestion == q)    // If m->CurrentQuestion was not auto-advanced, do it ourselves now
2877                         m->CurrentQuestion = q->next;
2878                 }
2879         m->CurrentQuestion = mDNSNULL;
2880         }
2881
2882 mDNSlocal void ReleaseCacheEntity(mDNS *const m, CacheEntity *e)
2883         {
2884 #if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
2885         unsigned int i;
2886         for (i=0; i<sizeof(*e); i++) ((char*)e)[i] = 0xFF;
2887 #endif
2888         e->next = m->rrcache_free;
2889         m->rrcache_free = e;
2890         m->rrcache_totalused--;
2891         }
2892
2893 mDNSlocal void ReleaseCacheGroup(mDNS *const m, CacheGroup **cp)
2894         {
2895         CacheEntity *e = (CacheEntity *)(*cp);
2896         //LogMsg("ReleaseCacheGroup:  Releasing CacheGroup for %p, %##s", (*cp)->name->c, (*cp)->name->c);
2897         if ((*cp)->rrcache_tail != &(*cp)->members)
2898                 LogMsg("ERROR: (*cp)->members == mDNSNULL but (*cp)->rrcache_tail != &(*cp)->members)");
2899         //if ((*cp)->name != (domainname*)((*cp)->namestorage))
2900         //      LogMsg("ReleaseCacheGroup: %##s, %p %p", (*cp)->name->c, (*cp)->name, (domainname*)((*cp)->namestorage));
2901         if ((*cp)->name != (domainname*)((*cp)->namestorage)) mDNSPlatformMemFree((*cp)->name);
2902         (*cp)->name = mDNSNULL;
2903         *cp = (*cp)->next;                      // Cut record from list
2904         ReleaseCacheEntity(m, e);
2905         }
2906
2907 mDNSlocal void ReleaseCacheRecord(mDNS *const m, CacheRecord *r)
2908         {
2909         //LogMsg("ReleaseCacheRecord: Releasing %s", CRDisplayString(m, r));
2910         if (r->resrec.rdata && r->resrec.rdata != (RData*)&r->smallrdatastorage) mDNSPlatformMemFree(r->resrec.rdata);
2911         r->resrec.rdata = mDNSNULL;
2912         ReleaseCacheEntity(m, (CacheEntity *)r);
2913         }
2914
2915 // Note: We want to be careful that we deliver all the CacheRecordRmv calls before delivering
2916 // CacheRecordDeferredAdd calls. The in-order nature of the cache lists ensures that all
2917 // callbacks for old records are delivered before callbacks for newer records.
2918 mDNSlocal void CheckCacheExpiration(mDNS *const m, CacheGroup *const cg)
2919         {
2920         CacheRecord **rp = &cg->members;
2921
2922         if (m->lock_rrcache) { LogMsg("CheckCacheExpiration ERROR! Cache already locked!"); return; }
2923         m->lock_rrcache = 1;
2924
2925         while (*rp)
2926                 {
2927                 CacheRecord *const rr = *rp;
2928                 mDNSs32 event = RRExpireTime(rr);
2929                 if (m->timenow - event >= 0)    // If expired, delete it
2930                         {
2931                         *rp = rr->next;                         // Cut it from the list
2932                         verbosedebugf("CheckCacheExpiration: Deleting%7d %7d %p %s",
2933                                 m->timenow - rr->TimeRcvd, rr->resrec.rroriginalttl, rr->CRActiveQuestion, CRDisplayString(m, rr));
2934                         if (rr->CRActiveQuestion)       // If this record has one or more active questions, tell them it's going away
2935                                 {
2936                                 DNSQuestion *q = rr->CRActiveQuestion;
2937                                 // When a cache record is about to expire, we expect to do four queries at 80-82%, 85-87%, 90-92% and
2938                                 // then 95-97% of the TTL. If the DNS server does not respond, then we will remove the cache entry
2939                                 // before we pick a new DNS server. As the question interval is set to MaxQuestionInterval, we may
2940                                 // not send out a query anytime soon. Hence, we need to reset the question interval. If this is
2941                                 // a normal deferred ADD case, then AnswerCurrentQuestionWithResourceRecord will reset it to
2942                                 // MaxQuestionInterval.
2943                                 if (!mDNSOpaque16IsZero(q->TargetQID) && !q->LongLived)
2944                                         {
2945                                         q->ThisQInterval = InitialQuestionInterval;
2946                                         q->LastQTime     = m->timenow - q->ThisQInterval;
2947                                         SetNextQueryTime(m, q);
2948                                         }
2949                                 CacheRecordRmv(m, rr);
2950                                 m->rrcache_active--;
2951                                 }
2952                         ReleaseCacheRecord(m, rr);
2953                         }
2954                 else                                                    // else, not expired; see if we need to query
2955                         {
2956                         if (rr->DelayDelivery && rr->DelayDelivery - m->timenow > 0)
2957                                 event = rr->DelayDelivery;
2958                         else
2959                                 {
2960                                 if (rr->DelayDelivery) CacheRecordDeferredAdd(m, rr);
2961                                 if (rr->CRActiveQuestion && rr->UnansweredQueries < MaxUnansweredQueries)
2962                                         {
2963                                         if (m->timenow - rr->NextRequiredQuery < 0)             // If not yet time for next query
2964                                                 event = rr->NextRequiredQuery;                          // then just record when we want the next query
2965                                         else                                                                                    // else trigger our question to go out now
2966                                                 {
2967                                                 // Set NextScheduledQuery to timenow so that SendQueries() will run.
2968                                                 // SendQueries() will see that we have records close to expiration, and send FEQs for them.
2969                                                 m->NextScheduledQuery = m->timenow;
2970                                                 // After sending the query we'll increment UnansweredQueries and call SetNextCacheCheckTime(),
2971                                                 // which will correctly update m->NextCacheCheck for us.
2972                                                 event = m->timenow + 0x3FFFFFFF;
2973                                                 }
2974                                         }
2975                                 }
2976                         verbosedebugf("CheckCacheExpiration:%6d %5d %s",
2977                                 (event - m->timenow) / mDNSPlatformOneSecond, CacheCheckGracePeriod(rr), CRDisplayString(m, rr));
2978                         if (m->NextCacheCheck - (event + CacheCheckGracePeriod(rr)) > 0)
2979                                 m->NextCacheCheck = (event + CacheCheckGracePeriod(rr));
2980                         rp = &rr->next;
2981                         }
2982                 }
2983         if (cg->rrcache_tail != rp) verbosedebugf("CheckCacheExpiration: Updating CacheGroup tail from %p to %p", cg->rrcache_tail, rp);
2984         cg->rrcache_tail = rp;
2985         m->lock_rrcache = 0;
2986         }
2987
2988 mDNSlocal void AnswerNewQuestion(mDNS *const m)
2989         {
2990         mDNSBool ShouldQueryImmediately = mDNStrue;
2991         DNSQuestion *q = m->NewQuestions;               // Grab the question we're going to answer
2992         const mDNSu32 slot = HashSlot(&q->qname);
2993         CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
2994
2995         verbosedebugf("AnswerNewQuestion: Answering %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
2996
2997         if (cg) CheckCacheExpiration(m, cg);
2998         m->NewQuestions = q->next;                              // Advance NewQuestions to the next *after* calling CheckCacheExpiration();
2999
3000         if (m->lock_rrcache) LogMsg("AnswerNewQuestion ERROR! Cache already locked!");
3001         // This should be safe, because calling the client's question callback may cause the
3002         // question list to be modified, but should not ever cause the rrcache list to be modified.
3003         // If the client's question callback deletes the question, then m->CurrentQuestion will
3004         // be advanced, and we'll exit out of the loop
3005         m->lock_rrcache = 1;
3006         if (m->CurrentQuestion)
3007                 LogMsg("AnswerNewQuestion ERROR m->CurrentQuestion already set: %##s (%s)",
3008                         m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
3009         m->CurrentQuestion = q;         // Indicate which question we're answering, so we'll know if it gets deleted
3010
3011         if (q->NoAnswer == NoAnswer_Fail)
3012                 {
3013                 LogMsg("AnswerNewQuestion: NoAnswer_Fail %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
3014                 MakeNegativeCacheRecord(m, &m->rec.r, &q->qname, q->qnamehash, q->qtype, q->qclass, 60, mDNSInterface_Any, q->qDNSServer);
3015                 q->NoAnswer = NoAnswer_Normal;          // Temporarily turn off answer suppression
3016                 AnswerCurrentQuestionWithResourceRecord(m, &m->rec.r, QC_addnocache);
3017                 q->NoAnswer = NoAnswer_Fail;            // Restore NoAnswer state
3018                 m->rec.r.resrec.RecordType = 0;         // Clear RecordType to show we're not still using it
3019                 }
3020
3021         // If 'mDNSInterface_Any' question, see if we want to tell it about LocalOnly records
3022         if (m->CurrentQuestion == q && q->InterfaceID == mDNSInterface_Any)
3023                 {
3024                 if (m->CurrentRecord)
3025                         LogMsg("AnswerNewQuestion ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
3026                 m->CurrentRecord = m->ResourceRecords;
3027                 while (m->CurrentRecord && m->CurrentRecord != m->NewLocalRecords)
3028                         {
3029                         AuthRecord *rr = m->CurrentRecord;
3030                         m->CurrentRecord = rr->next;
3031                         if (rr->resrec.InterfaceID == mDNSInterface_LocalOnly)
3032                                 if (ResourceRecordAnswersQuestion(&rr->resrec, q))
3033                                         {
3034                                         AnswerLocalQuestionWithLocalAuthRecord(m, q, rr, mDNStrue);
3035                                         if (m->CurrentQuestion != q) break;             // If callback deleted q, then we're finished here
3036                                         }
3037                         }
3038                 m->CurrentRecord = mDNSNULL;
3039                 }
3040
3041         if (m->CurrentQuestion != q) debugf("AnswerNewQuestion: question deleted while giving LocalOnly record answers");
3042
3043         if (m->CurrentQuestion == q)
3044                 {
3045                 CacheRecord *rr;
3046                 for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
3047                         if (SameNameRecordAnswersQuestion(&rr->resrec, q))
3048                                 {
3049                                 // SecsSinceRcvd is whole number of elapsed seconds, rounded down
3050