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