Lines Matching defs:question
136 // A, AAAA , CNAME, or PTR. The caller should answer the question with this record and not send out
137 // the question on the wire if LocalOnlyRecordAnswersQuestion() also returns true.
167 // Depending on whether this is a multicast or unicast question we want to set either:
449 LogInfo("GenerateNegativeResponse: Generating negative response for question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
455 // b) Append search domains and retry the question
457 // The question may not have set Intermediates in which case we don't deliver negative responses. So, to force
460 if (m->CurrentQuestion == q) { q->ThisQInterval = 0; } // Deactivate this question
461 // Don't touch the question after this
481 // both A and AAAA question and while answering it we don't want to throw
495 // A and B, and when we stop question A, UpdateQuestionDuplicates copies the value of CNAMEReferrals
497 // the target name is still the same), and then when we stop question B, UpdateQuestionDuplicates
500 // those cases the newly re-appended question A has a different target name and therefore cannot be
501 // a duplicate of any other question ('B') which was itself a duplicate of the previous question A.
529 // We have a message waiting and that should answer this question.
539 // Note: All the callers should use the m->CurrentQuestion to see if the question is still valid or not
577 // The callback above could have caused the question to stop. Detect that
618 // our main question list, delivering answers to mDNSInterface_Any questions as appropriate,
686 // Number of wakeups we send if WakeOnResolve is set in the question
1521 // Note: mDNS_Deregister_internal can call a user callback, which may change the record list and/or question list.
1638 // The AnswerAllLocalQuestionsWithLocalAuthRecord routine walks the question list invoking client callbacks, using the "m->CurrentQuestion"
1639 // mechanism to cope with the client callback modifying the question list while that's happening.
1693 // We may want to consider changing this code so that we generate local-only question "rmv"
2000 // which may change the record list and/or question list.
2326 // the record list and/or question list.
2888 // If we have an active question, then see if we want to schedule a refresher query for this record.
2929 // BuildQuestion puts a question into a DNS Query packet and if successful, updates the value of queryptr.
2942 debugf("BuildQuestion: No more space in this packet for question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
2958 SameNameRecordAnswersQuestion(&rr->resrec, q) && // which answers our question
2972 // If we're trying to put more than one question in this packet, and it doesn't fit
2973 // then undo that last question and try again next time
2977 debugf("BuildQuestion: Retracting question %##s (%s) new forecast total %d, total questions %d",
2994 SameNameRecordAnswersQuestion(&rr->resrec, q)) // which answers our question
3172 LogMsg("mDNSSendWakeOnResolve: ERROR!! Invalid InterfaceID %p for question %##s", InterfaceID, q->qname.c);
3232 SameNameRecordAnswersQuestion(&rr->resrec, q) && // which answers our question
3247 // 1. The Question Section contains the question
3305 // Indicate that this question was marked for sending
3350 q->SendQNow = mDNSInterfaceMark; // Mark this question for sending on all interfaces
3356 // m->CurrentQuestion point to the right question
3361 LogInfo("SendQueries question loop 1: Skipping NewQuestion %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
3371 // 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.
3383 // If we have reached the answer threshold for this question,
3401 // Mark this question for sending on all interfaces
3436 // If we recorded a duplicate suppression for this question less than half an interval ago,
3561 debugf("SendQueries: %s question for %##s (%s) at %d forecast total %d",
3571 // If we're suppressing this question, or we successfully put it, update its SendQNow state
3575 // We successfully added the question to the packet. Make sure that
3587 debugf("SendQueries: marking for question %##s, Suppress %d", q->qname.c, Suppress);
3597 // use brackground traffic class if any included question requires it
3628 // Put our known answer list (either new one from this question or questions, or remainder of old one from last time)
3645 // If we ran out of space and we have more than one question in the packet, that's an error --
3646 // we shouldn't have put more than one question if there was a risk of us running out of space.
3726 LogMsg("SendQueries: Should not have more than one question (%d) in a truncated packet", m->omsg.h.numQuestions);
3788 for (x = m->NewQuestions; x; x=x->next) if (x == q) break; // Check if this question is a NewQuestion
3789 LogInfo("SendQueries: No active interface %d to send %s question: %d %##s (%s)",
3840 // Whenever a question is answered, reset its state so that we don't query
3841 // the network repeatedly. This happens first time when we answer the question and
3856 // Note: AnswerCurrentQuestionWithResourceRecord can call a user callback, which may change the record list and/or question list.
3858 // In fact, to enforce this, the routine will *only* answer the question currently pointed to by m->CurrentQuestion,
3859 // which will be auto-advanced (possibly to NULL) if the client callback cancels the question.
3868 // When the response for the question was validated, the entire rrset was validated. If we deliver
3939 // for the purpose of retrying search domains/timeout OR the question is suppressed
3957 // If this is an "Add" operation and this question needs validation, validate the response.
3986 // don't follow them. If it is a ValidationRequired question, wait for the CNAME to be validated
4030 // 2) A new question is about to be answered and the caller needs to know whether it's
4031 // scheduling should be delayed so that the question is not answered with this record.
4033 // (new entry), a single ADD can be delivered by delaying the scheduling of the question
4045 // Also, if there is already an active question we don't try to optimize as purging the cache
4046 // would end up delivering RMV for the active question and hence we avoid that.
4073 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
4077 // which may change the record list and/or question list.
4089 // If this question is one that's actively sending queries, and it's received ten answers within one
4108 verbosedebugf("CacheRecordAdd %p %##s (%s) %lu %#a:%d question %p", rr, rr->resrec.name->c,
4150 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
4152 // but we don't have any place to cache it. We'll deliver question 'add' events now, but we won't have any
4156 // which may change the record list and/or question list.
4178 // Note that CacheRecordRmv is *only* called for records that are referenced by at least one active question.
4180 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
4184 // which may change the record list and/or question list.
4198 // When a question enters suppressed state, we generate RMV events and generate a negative
4199 // response. A cache may be present that answers this question e.g., cache entry generated
4200 // before the question became suppressed. We need to skip the suppressed questions here as
4221 // If we have dropped below the answer threshold for this mDNS question,
4374 // before we pick a new DNS server. As the question interval is set to MaxQuestionInterval, we may
4375 // not send out a query anytime soon. Hence, we need to reset the question interval. If this is
4402 else // else trigger our question to go out now
4427 // If "CheckOnly" is set to "true", the question won't be answered but just check to see if there is an answer and
4430 // If "CheckOnly" is set to "false", the question will be answered if there is a LocalOnly/P2P record and
4451 // If the question is mDNSInterface_LocalOnly, all records local to the machine should be used
4463 LogInfo("AnswerQuestionWithLORecord: question %##s (%s) answered by %s", q->qname.c, DNSTypeName(q->qtype),
4490 // no local records that could possibly answer this question. As we did not check the NewLocalRecords, we
4491 // need to just peek at them to see whether it will answer this question. If it would answer, pretend
4493 // when we add new /etc/hosts entries and restart the question. It is a new question and also a new record.
4535 DNSQuestion *const q = m->NewQuestions; // Grab the question we're going to answer
4546 // then CheckCacheExpiration may give this question add/remove callbacks, and it's not yet ready for that.
4549 // client callbacks, which may delete their own or any other question. Our mechanism for detecting
4550 // whether our current m->NewQuestions question got deleted by one of these callbacks is to store the
4553 // advanced it), that means the question was deleted, so we no longer need to worry about answering
4555 // values we computed for slot and cg are now stale and relate to a question that no longer exists).
4560 // deleting a question, so luckily we have an easy alternative way of detecting if our question got deleted.
4563 // This should be safe, because calling the client's question callback may cause the
4564 // question list to be modified, but should not ever cause the rrcache list to be modified.
4565 // If the client's question callback deletes the question, then m->CurrentQuestion will
4571 m->CurrentQuestion = q; // Indicate which question we're answering, so we'll know if it gets deleted
4579 // Don't touch the question if it has been stopped already
4595 // If we are not supposed to answer this question, generate a negative response.
4596 // Temporarily suspend the SuppressQuery so that AnswerCurrentQuestionWithResourceRecord can answer the question
4598 // If it is a question trying to validate some response, it already checked the cache for a response. If it still
4599 // reissues a question it means it could not find the RRSIGs. So, we need to bypass the cache check and send
4600 // the question out.
4638 // Neither a local record nor a cache entry could answer this question. If this question need to be retried
4650 // Note: When a query gets suppressed or retried with search domains, we de-activate the question.
4668 // answers for this question until *after* its scheduled transmission time, in which case
4684 DNSQuestion *q = m->NewLocalOnlyQuestions; // Grab the question we're going to answer
4692 m->CurrentQuestion = q; // Indicate which question we're answering, so we'll know if it gets deleted
4697 // 1. First walk the LocalOnly records answering the LocalOnly question
4977 LogInfo("TimeoutQuestions: question %p %##s timed out, time %d", q, q->qname.c, m->timenow - q->StopTime);
4989 // depends on having m->CurrentQuestion point to the right question
5312 // 1. When a new question is created
5316 // In cases 2 and 3 we do want to cause the question to be resent immediately (ScheduleImmediately is true)
5317 mDNSlocal void ActivateUnicastQuery(mDNS *const m, DNSQuestion *const question, mDNSBool ScheduleImmediately)
5329 if (RRTypeIsAddressType(question->qtype) && PrivateQuery(question) &&
5330 !SameDomainLabel(question->qname.c, (const mDNSu8 *)"\x0c_autotunnel6")&& question->QuestionCallback != AutoTunnelCallback)
5332 question->NoAnswer = NoAnswer_Suspended;
5333 AddNewClientTunnel(m, question);
5338 if (!question->DuplicateOf)
5341 question->qname.c, DNSTypeName(question->qtype), PrivateQuery(question) ? " (Private)" : "", ScheduleImmediately ? " ScheduleImmediately" : "");
5342 question->CNAMEReferrals = 0;
5343 if (question->nta) { CancelGetZoneData(m, question->nta); question->nta = mDNSNULL; }
5344 if (question->LongLived)
5346 question->state = LLQ_InitialRequest;
5347 question->id = zeroOpaque64;
5348 question->servPort = zeroIPPort;
5349 if (question->tcp) { DisposeTCPConn(question->tcp); question->tcp = mDNSNULL; }
5351 // If the question has local answers, then we don't want answers from outside
5352 if (ScheduleImmediately && !QuestionHasLocalAnswers(m, question))
5354 question->ThisQInterval = InitialQuestionInterval;
5355 question->LastQTime = m->timenow - question->ThisQInterval;
5356 SetNextQueryTime(m, question);
5374 // we are going to stop the question. Hence we need to deliver the RMV event before we
5375 // stop the question.
5378 // application callback can potentially stop the current question (detected by CurrentQuestion) or
5379 // *any* other question which could be the next one that we may process here. RestartQuestion
5380 // points to the "next" question which will be automatically advanced in mDNS_StopQuery_internal
5381 // if the "next" question is stopped while the CurrentQuestion is stopped
5393 // question) through their "nta" pointer. Normally when the original query stops, it stops the
5394 // GetZoneData question and also frees the memory (See CancelGetZoneData). If we stop the GetZoneData
5395 // question followed by the original query that refers to this GetZoneData question, we will end up
5396 // freeing the GetZoneData question and then start the "freed" question at the end.
5402 // debug stuff, we just try to find the referencing question and don't do much with it
5405 if (q == &refq->nta->question)
5437 LogInfo("mDNSCoreRestartAddressQueries: Stop question %p %##s (%s), AppendSearchDomains %d, qnameOrig %p", q,
5465 LogInfo("mDNSCoreRestartAddressQueries: Start question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
5493 // restart question if it's multicast and currently active
5498 q->ThisQInterval = InitialQuestionInterval; // MUST be > zero for an active question
6069 mDNSlocal void NetWakeResolve(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
6071 NetworkInterfaceInfo *intf = (NetworkInterfaceInfo *)question->QuestionContext;
6072 int sps = (int)(question - intf->NetWakeResolve);
6077 if (answer->rrtype != question->qtype) return; // Don't care about CNAMEs
6084 mDNS_StopQuery(m, question);
6086 AssignDomainName(&question->qname, &answer->rdata->u.srv.target);
6087 question->qtype = kDNSType_A;
6088 mDNS_StartQuery(m, question);
6093 mDNS_StopQuery(m, question);
6094 question->ThisQInterval = -1;
6104 mDNS_StopQuery(m, question);
6105 LogSPS("NetWakeResolve: SPS %d %##s has no IPv4 address, will try IPv6 instead", sps, question->qname.c);
6106 question->qtype = kDNSType_AAAA;
6107 mDNS_StartQuery(m, question);
6112 mDNS_StopQuery(m, question);
6113 question->ThisQInterval = -1;
6784 for (i=0; i<query->h.numQuestions; i++) // For each question...
6787 ptr = getQuestion(query, ptr, end, InterfaceID, &q); // get the question...
6792 if (rr->NR_AnswerTo == ptr) // If we're going to generate a record answering this question
6793 { // then put the question in the question section
6796 break; // break out of the ResponseRecords loop, and go on to the next question
6942 // the record list and/or question list.
7172 for (i=0; i<query->h.numQuestions; i++) // For each question...
7178 ptr = getQuestion(query, ptr, end, InterfaceID, &pktq); // get the question...
7204 // can result in user callbacks which may change the record list and/or question list.
7225 // As we have verified this question to be part of the same subset,
7244 // We only mark this question for sending if it is at least one second since the last time we multicast it
7256 // If we don't have any answers for this question, but we do own another record with the same name,
7270 // If we couldn't answer this question, someone else might be able to,
7279 // We only do the following accelerated cache expiration and duplicate question suppression processing
7317 // Check if this question is the same as any of mine.
7324 // For anonymous question, the duplicate suppressesion should happen if the
7325 // question belongs in the same group. As the group is expected to be
7743 mDNSlocal DNSQuestion *ExpectingUnicastResponseForQuestion(const mDNS *const m, const mDNSIPPort port, const mDNSOpaque16 id, const DNSQuestion *const question, mDNSBool tcp)
7751 q->qtype == question->qtype &&
7752 q->qclass == question->qclass &&
7753 q->qnamehash == question->qnamehash &&
7754 SameDomainName(&q->qname, &question->qname))
7845 // 1. If a resource record answers question, cache it. This also will cache NSECs if it asserts
7846 // non-existence of q->qtype. If we have any matching NSEC3 Records for the question, send
7856 // The record and the question belong to the same subset. Set the
7864 LogInfo("ExpectingMulticastResponseForRecord: record %s, question %##s (%s)", CRDisplayString(m, rr), q->qname.c, DNSTypeName(q->qtype));
7872 // If question is for a sub type, just compare against the primary service type
7880 LogInfo("ExpectingMulticastResponseForRecord: Accepting %s due to PTR match, question %##s from %#a, pktnum %d",
7892 // 3. Same as in (2), but look in the cache in case we don't have the PTR question.
7951 // if it finds a matching question with this record, it bumps up the counters like
8071 // When the response does not match the question directly, we still want to cache them sometimes. The current response is
8084 // match the question and we already created a cache entry in the previous pass of this loop. Now when we process
8085 // the A record, it does not match the question because the record name here is the CNAME. Hence we try to
8096 // Either the question requires validation or we are validating a response with DNSSEC in which case
8109 // We cache RRSIGS if it covers the question type or NSEC. If it covers a NSEC,
8124 LogInfo("IsResponseAcceptable: Accepting RRSIG %s matches question type %s", CRDisplayString(m, newcr),
8181 // information to ValidatingResponse question to indicate the DNSSEC status to the application
8199 LogMsg("mDNSCoreReceiveNoDNSSECAnswers: ERROR!! qptr %##s (%s) Duplicate question matching response", qptr->qname.c, DNSTypeName(qptr->qtype));
8202 // question. If we called the callback on the original question, it could stop and
8203 // a duplicate question would become the original question.
8211 LogInfo("mDNSCoreReceiveNoDNSSECAnswers: qptr %##s (%s) Duplicate question found", q->qname.c, DNSTypeName(q->qtype));
8213 LogMsg("mDNSCoreReceiveNoDNSSECAnswers: ERROR!! qptr %##s (%s) Duplicate question not ValidatingResponse", q->qname.c, DNSTypeName(q->qtype));
8261 // By suppressing negative responses, it might take longer to timeout a .local question as it might be expecting a
8365 // When we created the cache for the first time and answered the question, the question's
8369 // we should reset its question interval here to MaxQuestionInterval.
8600 // record in the list that answers the question so that it can be used for validation
8602 // that would answer the question. It is possible that we might cache additional things
8603 // e.g., MX question might cache A records also, and we want to cache the NSEC on
8604 // the record that answers the question.
8611 // We have to reset the question interval to MaxQuestionInterval so that we don't keep
8615 // configuration changed, without flushing the cache, we reset the question interval here.
8731 // the record list and/or question list.
8819 // answer questions in this packet's question section, but which aren't tagged with this packet's
8830 // Remember the unicast question that we found, which we use to make caching
8858 LogInfo("mDNSCoreReceiveResponse: CRDNSSECQuestion set for record %s, question %##s (%s)", CRDisplayString(m, rr),
8870 // req_DO to false here, the next retransmission for this question will turn off validation
8918 // to any specific question -- any code reading records from the cache needs to make that determination for itself.)
8982 // queries to get ADD/RMV events. To lookup the question, we can't use
8984 // has already matched the question using the 64 bit Id in the packet and we use that here.
8988 // If this is a DNSSEC question that is also LongLived, don't accept records from the
9013 // on the "id" and "source port", then this response answers the question and assume the response
9029 // If we can't find a matching question, we need to see whether we have seen records earlier that matched
9030 // the question. The code below does that. So, make this record unacceptable for now
9033 debugf("mDNSCoreReceiveResponse: Can't find question for record name %##s", m->rec.r.resrec.name->c);
9042 LogInfo("mDNSCoreReceiveResponse: Accepting record in response to QU question %s, InterfaceID %p", CRDisplayString(m, &m->rec.r),
9253 // Remember whether we created a cache record in response to a DNSSEC question.
9254 // This helps DNSSEC code not to reissue the question to fetch the DNSSEC records.
9258 LogInfo("mDNSCoreReceiveResponse: CRDNSSECQuestion set for new record %s, question %##s (%s)", CRDisplayString(m, rr),
9424 // If we had a unicast question for this response with at least one positive answer and we
9468 // ValidatingResponse question waiting for this response, give a hint that no RRSIGs
10353 // is suppressed. If it is not suppressed, we do try all the DNS servers for valid answers like any other question.
10354 // The main reason for this design is that cache entries point to a *single* question and that question is responsible
10355 // for keeping the cache fresh as long as it is active. Having multiple active question for a single cache entry
10359 // If IsLLQ(Q) is true, it means the question is both:
10366 mDNSlocal DNSQuestion *FindDuplicateQuestion(const mDNS *const m, const DNSQuestion *const question)
10369 // Note: A question can only be marked as a duplicate of one that occurs *earlier* in the list.
10371 // Accordingly, we break out of the loop when we get to 'question', because there's no point searching
10373 for (q = m->Questions; q && q != question; q=q->next) // Scan our list for another question
10374 if (q->InterfaceID == question->InterfaceID && // with the same InterfaceID,
10375 SameQTarget(q, question) && // and same unicast/multicast target settings
10376 q->qtype == question->qtype && // type,
10377 q->qclass == question->qclass && // class,
10378 IsLLQ(q) == IsLLQ(question) && // and long-lived status matches
10379 (!q->AuthInfo || question->AuthInfo) && // to avoid deadlock, don't make public query dup of a private one
10380 (q->AnonInfo == question->AnonInfo) && // Anonymous query not a dup of normal query
10381 (q->SuppressQuery == question->SuppressQuery) && // Questions that are suppressed/not suppressed
10382 (q->ValidationRequired == question->ValidationRequired) && // Questions that require DNSSEC validation
10383 (q->ValidatingResponse == question->ValidatingResponse) && // Questions that are validating responses using DNSSEC
10384 (q->DisallowPID == question->DisallowPID) && // Disallowing a PID should not affect a PID that is allowed
10385 (q->BrowseThreshold == question->BrowseThreshold) && // browse thresholds must match
10386 q->qnamehash == question->qnamehash &&
10387 (IsAWDLIncluded(q) == IsAWDLIncluded(question)) && // Inclusion of AWDL interface must match
10388 SameDomainName(&q->qname, &question->qname)) // and name
10393 // This is called after a question is deleted, in case other identical questions were being suppressed as duplicates
10394 mDNSlocal void UpdateQuestionDuplicates(mDNS *const m, DNSQuestion *const question)
10399 // This is referring to some other question as duplicate. No other question can refer to this
10400 // question as a duplicate.
10401 if (question->DuplicateOf)
10403 LogInfo("UpdateQuestionDuplicates: question %p %##s (%s) duplicate of %p %##s (%s)",
10404 question, question->qname.c, DNSTypeName(question->qtype),
10405 question->DuplicateOf, question->DuplicateOf->qname.c, DNSTypeName(question->DuplicateOf->qtype));
10410 if (q->DuplicateOf == question) // To see if any questions were referencing this as their duplicate
10417 // then inherit the state from the question that's going away
10418 q->LastQTime = question->LastQTime;
10419 q->ThisQInterval = question->ThisQInterval;
10420 q->ExpectUnicastResp = question->ExpectUnicastResp;
10421 q->LastAnswerPktNum = question->LastAnswerPktNum;
10422 q->RecentAnswerPkts = question->RecentAnswerPkts;
10423 q->RequestUnicast = question->RequestUnicast;
10424 q->LastQTxTime = question->LastQTxTime;
10425 q->CNAMEReferrals = question->CNAMEReferrals;
10426 q->nta = question->nta;
10427 q->servAddr = question->servAddr;
10428 q->servPort = question->servPort;
10429 q->qDNSServer = question->qDNSServer;
10430 q->validDNSServers = question->validDNSServers;
10431 q->unansweredQueries = question->unansweredQueries;
10432 q->noServerResponse = question->noServerResponse;
10433 q->triedAllServersOnce = question->triedAllServersOnce;
10435 q->TargetQID = question->TargetQID;
10441 q->LocalSocket = question->LocalSocket;
10443 q->state = question->state;
10444 // q->tcp = question->tcp;
10445 q->ReqLease = question->ReqLease;
10446 q->expire = question->expire;
10447 q->ntries = question->ntries;
10448 q->id = question->id;
10450 question->LocalSocket = mDNSNULL;
10451 question->nta = mDNSNULL; // If we've got a GetZoneData in progress, transfer it to the newly active question
10452 // question->tcp = mDNSNULL;
10464 if (question->tcp) LogInfo("UpdateQuestionDuplicates did not transfer tcp pointer");
10466 if (question->state == LLQ_Established)
10469 question->state = 0; // Must zero question->state, or mDNS_StopQuery_internal will clean up and cancel our LLQ from the server
10575 mDNSlocal mDNSu32 GetTimeoutForMcastQuestion(mDNS *m, DNSQuestion *question)
10578 int bestmatchlen = -1, namecount = CountLabels(&question->qname);
10584 bettermatch = BetterMatchForName(&question->qname, namecount, &curr->domain, currcount, bestmatchlen);
10593 LogInfo("GetTimeoutForMcastQuestion: question %##s curmatch %p, Timeout %d", question->qname.c, curmatch,
10608 if (CountLabels(qname) < 4) { debugf("DomainEnumQuery: question %##s, not enough labels", qname->c); return mDNSfalse; }
10647 // Note: InterfaceID is the InterfaceID of the question
10659 // The first condition in the "if" statement checks to see if both the question and the DNSServer are
10660 // unscoped. The question is unscoped only if InterfaceID is zero and ServiceID is -1.
10669 // unscoped question should not match scoped DNSServer (Refer to (1) above). The InterfaceID check
10672 // - DNSServer is scoped and InterfaceID is not NULL - the InterfaceID of the question and the DNSServer
10676 // If a question is scoped both to InterfaceID and ServiceID, the question will be scoped to InterfaceID.
10687 // Sets all the Valid DNS servers for a question
10688 mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
10690 int bestmatchlen = -1, namecount = CountLabels(&question->qname);
10697 question->validDNSServers = zeroOpaque64;
10698 DEQuery = DomainEnumQuery(&question->qname);
10724 if ((!DEQuery || !curr->cellIntf) && DNSServerMatch(curr, question->InterfaceID, question->ServiceID))
10726 bettermatch = BetterMatchForName(&question->qname, namecount, &curr->domain, currcount, bestmatchlen);
10738 question->validDNSServers = zeroOpaque64;
10741 debugf("SetValidDNSServers: question %##s Setting the bit for DNS server Address %#a (Domain %##s), Scoped:%d index %d,"
10742 " Timeout %d, interface %p", question->qname.c, &curr->addr, curr->domain.c, curr->scoped, index, curr->timeout,
10746 debugf("DomainEnumQuery: Question %##s, DNSServer %#a, cell %d", question->qname.c, &curr->addr, curr->cellIntf);
10747 bit_set_opaque64(question->validDNSServers, index);
10752 question->noServerResponse = 0;
10754 debugf("SetValidDNSServers: ValidDNSServer bits 0x%x%x for question %p %##s (%s)",
10755 question->validDNSServers.l[1], question->validDNSServers.l[0], question, question->qname.c, DNSTypeName(question->qtype));
10758 return ((question->ProxyQuestion || question->ValidatingResponse) ? DEFAULT_UDNSSEC_TIMEOUT : timeout ? timeout : DEFAULT_UDNS_TIMEOUT);
10799 // If there are multiple best servers for a given question, we will pick the first one
10810 // This happens when we initially walk all the DNS servers and set the validity bit on the question.
10864 // Look up a DNS Server for a question within its valid DNSServer bits
10865 mDNSexport DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question)
10869 mDNSInterfaceID InterfaceID = question->InterfaceID;
10870 const domainname *name = &question->qname;
10879 if (!mDNSOpaque64IsZero(&question->validDNSServers))
10881 curmatch = GetBestServer(m, name, InterfaceID, question->ServiceID, question->validDNSServers, &currindex, mDNSfalse);
10883 bit_clr_opaque64(question->validDNSServers, currindex);
10889 question, curmatch, &curmatch->addr, mDNSVal16(curmatch->port),
10891 InterfaceID, question->ServiceID, name, DNSTypeName(question->qtype));
10896 question, ifname ? ifname : "None", InterfaceID, question->ServiceID, name, DNSTypeName(question->qtype));
11009 // 1. If we find a LocalOnly or P2P record answering this question, then don't suppress it.
11022 // 2. If we find a local AuthRecord answering this question, then don't suppress it.
11045 // the question.
11050 LogInfo("ShouldSuppressQuery: Query not suppressed for %##s, qtype %s, Local question", q->qname.c, DNSTypeName(q->qtype));
11055 LogInfo("ShouldSuppressQuery: Query suppressed for %##s, qtype %s, Local question", q->qname.c, DNSTypeName(q->qtype));
11076 LogInfo("CacheRecordRmvEventsForCurrentQuestion: CacheRecord %s Suppressing RMV events for question %p %##s (%s), CRActiveQuestion %p, CurrentAnswers %d",
11083 LogInfo("CacheRecordRmvEventsForCurrentQuestion: Calling AnswerCurrentQuestionWithResourceRecord (RMV) for question %##s using resource record %s LocalAnswers %d",
11093 // If this was the active question for this cache entry, it was the one that was
11096 // when the cache entry is about to expire, we won't find an active question
11104 "Original question CurrentAnswers %d, new question CurrentAnswers %d, SuppressUnusable %d, SuppressQuery %d",
11116 mDNSlocal mDNSBool IsQuestionNew(mDNS *const m, DNSQuestion *question)
11120 if (q == question) return mDNStrue;
11165 // Returns false if the question got deleted while delivering the RMV events
11173 // If it is a new question, we have not delivered any ADD events yet. So, don't deliver RMV events.
11174 // If this question was answered using local auth records, then you can't deliver RMVs using cache
11182 else { LogInfo("CacheRecordRmvEventsForQuestion: Question %p %##s (%s) is a new question", q, q->qname.c, DNSTypeName(q->qtype)); }
11204 // question below, we need to deliver the RMV events so that the ADDs that will be delivered during
11214 // 1. Previously it was suppressed and now it is not suppressed, restart the question so
11215 // that it will start as a new question. Note that we can't just call ActivateUnicastQuery
11217 // this question if the cache entry did not change. Hence, we need to restart
11221 // so that we redo the duplicate checks in mDNS_StartQuery_internal. A SuppressUnusable question
11222 // is a duplicate of non-SuppressUnusable question if it is not suppressed (SuppressQuery is false).
11223 // A SuppressUnusable question is not a duplicate of non-SuppressUnusable question if it is suppressed
11224 // (SuppressQuery is true). The reason for this is that when a question is suppressed, we want an
11225 // immediate response and not want to be blocked behind a question that is querying DNS servers. When
11226 // the question is not suppressed, we don't want two active questions sending packets on the wire.
11227 // This affects both efficiency and also the current design where there is only one active question
11232 // If there are duplicate questions, calling stop inherits the values from another question on the list (which
11233 // will soon become the real question) including q->ThisQInterval which might be zero if it was
11239 LogInfo("SuppressStatusChanged: Stop question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
11258 // application callback can potentially stop the current question (detected by CurrentQuestion) or
11259 // *any* other question which could be the next one that we may process here. RestartQuestion
11260 // points to the "next" question which will be automatically advanced in mDNS_StopQuery_internal
11261 // if the "next" question is stopped while the CurrentQuestion is stopped
11278 // AnswerCurrentQuestionWithResourceRecord can answer the question
11288 LogInfo("CheckSuppressUnusableQuestions: Start question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
11309 LogMsg("RestartUnicastQuestions: ERROR!! Restart set for multicast question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
11320 LogInfo("RestartUnicastQuestions: Start question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
11328 mDNSlocal mStatus ValidateParameters(mDNS *const m, DNSQuestion *const question)
11331 if (question->Target.type && !ValidQuestionTarget(question))
11333 LogMsg("ValidateParameters: Warning! Target.type = %ld port = %u (Client forgot to initialize before calling mDNS_StartQuery? for question %##s)",
11334 question->Target.type, mDNSVal16(question->TargetPort), question->qname.c);
11335 question->Target.type = mDNSAddrType_None;
11338 // If no question->Target specified, clear TargetPort
11339 if (!question->Target.type)
11340 question->TargetPort = zeroIPPort;
11342 if (!ValidateDomainName(&question->qname))
11344 LogMsg("ValidateParameters: Attempt to start query with invalid qname %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
11348 // If this question is referencing a specific interface, verify it exists
11349 if (question->InterfaceID && question->InterfaceID != mDNSInterface_LocalOnly && question->InterfaceID != mDNSInterface_Unicast && question->InterfaceID != mDNSInterface_P2P)
11351 NetworkInterfaceInfo *intf = FirstInterfaceForID(m, question->InterfaceID);
11353 LogInfo("ValidateParameters: Note: InterfaceID %d for question %##s (%s) not currently found in active interface list",
11354 (uint32_t)question->InterfaceID, question->qname.c, DNSTypeName(question->qtype));
11362 mDNSlocal void InitDNSConfig(mDNS *const m, DNSQuestion *const question)
11365 question->qDNSServer = mDNSNULL;
11366 question->validDNSServers = zeroOpaque64;
11367 question->triedAllServersOnce = 0;
11368 question->noServerResponse = 0;
11369 question->StopTime = 0;
11372 if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P)
11375 if (!mDNSOpaque16IsZero(question->TargetQID))
11377 mDNSu32 timeout = SetValidDNSServers(m, question);
11386 // it gets a full timeout value even if the original question times out earlier.
11387 if (question->TimeoutQuestion)
11389 question->StopTime = NonZeroTime(m->timenow + timeout * mDNSPlatformOneSecond);
11390 LogInfo("InitDNSConfig: Setting StopTime on question %p %##s (%s)", question, question->qname.c, DNSTypeName(question->qtype));
11393 question->qDNSServer = GetServerForQuestion(m, question);
11394 LogInfo("InitDNSConfig: question %p %##s (%s) Timeout %d, DNS Server %#a:%d",
11395 question, question->qname.c, DNSTypeName(question->qtype), timeout,
11396 question->qDNSServer ? &question->qDNSServer->addr : mDNSNULL,
11397 mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zp));
11401 if (question->TimeoutQuestion)
11402 question->StopTime = NonZeroTime(m->timenow + GetTimeoutForMcastQuestion(m, question) * mDNSPlatformOneSecond);
11405 if (question->StopTime)
11406 SetNextQueryStopTime(m, question);
11409 SetNextQueryTime(m,question);
11414 mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
11419 // Note: In the case where we already have the answer to this question in our cache, that may be all the client
11420 // wanted, and they may immediately cancel their question. In this case, sending an actual query on the wire would
11424 question->next = mDNSNULL;
11427 // the question list to check if ThisQInterval is negative which means the question has been
11428 // stopped and can't be on the list. The question is already on the list and ThisQInterval
11432 question->ThisQInterval = InitialQuestionInterval; // MUST be > zero for an active question
11433 question->qnamehash = DomainNameHashValue(&question->qname);
11434 question->DelayAnswering = CheckForSoonToExpireRecords(m, &question->qname, question->qnamehash, HashSlot(&question->qname), &purge);
11435 question->LastQTime = m->timenow;
11436 question->ExpectUnicastResp = 0;
11437 question->LastAnswerPktNum = m->PktNum;
11438 question->RecentAnswerPkts = 0;
11439 question->CurrentAnswers = 0;
11448 if (question->flags & kDNSServiceFlagsThresholdOne)
11449 question->BrowseThreshold = 1;
11450 else if (question->flags & kDNSServiceFlagsThresholdFinder)
11451 question->BrowseThreshold = mDNSFinderBrowseThreshold;
11453 question->BrowseThreshold = 0;
11456 question->BrowseThreshold = 0;
11458 question->CachedAnswerNeedsUpdate = mDNSfalse;
11460 question->LargeAnswers = 0;
11461 question->UniqueAnswers = 0;
11462 question->LOAddressAnswers = 0;
11463 question->FlappingInterface1 = mDNSNULL;
11464 question->FlappingInterface2 = mDNSNULL;
11467 // since we would already have the question->ServiceID in that case.
11468 if (!(question->flags & kDNSServiceFlagsServiceIndex))
11469 question->ServiceID = mDNSPlatformGetServiceID(m, question);
11471 LogInfo("InitCommonState: Query for %##s (%s), PID[%d], ServiceID %d is already set by client", question->qname.c,
11472 DNSTypeName(question->qtype), question->pid, question->ServiceID);
11474 InitDNSConfig(m, question);
11476 question->AuthInfo = GetAuthInfoForQuestion(m, question);
11477 question->SuppressQuery = 0;
11478 if (question->SuppressUnusable)
11479 question->SuppressQuery = ShouldSuppressQuery(m, question);
11483 question->DisallowPID = (question->ServiceID == 0 || (mDNSPlatformAllowPID(m, question) == 0));
11484 if (question->DisallowPID)
11485 LogInfo("InitCommonState: Query suppressed for %##s (%s), PID %d/ServiceID %d not allowed", question->qname.c,
11486 DNSTypeName(question->qtype), question->pid, question->ServiceID);
11488 question->NextInDQList = mDNSNULL;
11489 question->SendQNow = mDNSNULL;
11490 question->SendOnAll = mDNSfalse;
11493 question->RequestUnicast = SET_QU_IN_FIRST_FOUR_QUERIES;
11495 question->RequestUnicast = SET_QU_IN_FIRST_QUERY;
11503 if (question->flags & kDNSServiceFlagsUnicastResponse)
11505 question->RequestUnicast = SET_QU_IN_FIRST_FOUR_QUERIES;
11506 LogInfo("InitCommonState: setting RequestUnicast = %d for %##s (%s)", question->RequestUnicast, question->qname.c,
11507 DNSTypeName(question->qtype));
11509 else if (question->flags & kDNSServiceFlagsThresholdFinder)
11513 question->RequestUnicast = SET_QU_IN_FIRST_FOUR_QUERIES;
11515 question->RequestUnicast = SET_QU_IN_FIRST_QUERY;
11519 question->RequestUnicast, question->qname.c, DNSTypeName(question->qtype));
11523 question->LastQTxTime = m->timenow;
11524 question->CNAMEReferrals = 0;
11526 question->WakeOnResolveCount = 0;
11527 if (question->WakeOnResolve)
11529 question->WakeOnResolveCount = InitialWakeOnResolveCount;
11534 question->DupSuppress[i].InterfaceID = mDNSNULL;
11536 question->Restart = 0;
11539 question->qname.c, DNSTypeName(question->qtype), question->InterfaceID, m->timenow,
11540 NextQSendTime(question) - m->timenow,
11541 question->DelayAnswering ? question->DelayAnswering - m->timenow : 0,
11542 question, question->DuplicateOf ? "duplicate of" : "not duplicate", question->DuplicateOf);
11544 if (question->DelayAnswering)
11546 question->DelayAnswering - m->timenow, question->qname.c, DNSTypeName(question->qtype));
11552 mDNSlocal void InitWABState(DNSQuestion *const question)
11554 // We'll create our question->LocalSocket on demand, if needed.
11558 question->LocalSocket = mDNSNULL;
11559 question->unansweredQueries = 0;
11560 question->nta = mDNSNULL;
11561 question->servAddr = zeroAddr;
11562 question->servPort = zeroIPPort;
11563 question->tcp = mDNSNULL;
11564 question->NoAnswer = NoAnswer_Normal;
11581 mDNSlocal void InitLLQState(DNSQuestion *const question)
11583 question->state = LLQ_InitialRequest;
11584 question->ReqLease = 0;
11585 question->expire = 0;
11586 question->ntries = 0;
11587 question->id = zeroOpaque64;
11592 mDNSlocal void InitDNSSECProxyState(mDNS *const m, DNSQuestion *const question)
11601 if (question->qDNSServer)
11603 if (question->qDNSServer->cellIntf)
11605 LogInfo("InitDNSSECProxyState: Turning off validation for %##s (%s); going over cell", question->qname.c, DNSTypeName(question->qtype));
11606 question->ValidationRequired = mDNSfalse;
11608 if (DNSSECOptionalQuestion(question) && !(question->qDNSServer->req_DO))
11611 question->qname.c, DNSTypeName(question->qtype));
11612 question->ValidationRequired = DNSSEC_VALIDATION_NONE;
11615 question->ValidationState = (question->ValidationRequired ? DNSSECValRequired : DNSSECValNotRequired);
11616 question->ValidationStatus = 0;
11617 question->responseFlags = zeroID;
11620 // Once the question is completely initialized including the duplicate logic, this function
11621 // is called to finalize the unicast question which requires flushing the cache if needed,
11623 mDNSlocal void FinalizeUnicastQuestion(mDNS *const m, DNSQuestion *question, mDNSBool purge)
11625 // Ensure DNS related info of duplicate question is same as the orig question
11626 if (question->DuplicateOf)
11629 question->validDNSServers = question->DuplicateOf->validDNSServers;
11630 question->qDNSServer = question->DuplicateOf->qDNSServer;
11631 LogInfo("FinalizeUnicastQuestion: Duplicate question %p (%p) %##s (%s), DNS Server %#a:%d",
11632 question, question->DuplicateOf, question->qname.c, DNSTypeName(question->qtype),
11633 question->qDNSServer ? &question->qDNSServer->addr : mDNSNULL,
11634 mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zp));
11637 ActivateUnicastQuery(m, question, mDNSfalse);
11640 // DNS server on the question
11643 question->DelayAnswering = 0;
11644 mDNS_PurgeForQuestion(m, question);
11646 else if (!question->DuplicateOf && DNSSECQuestion(question))
11649 CheckForDNSSECRecords(m, question);
11651 if (question->LongLived)
11654 // we determine that it is a unicast question. LongLived is set for
11665 mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const question)
11676 vStatus = ValidateParameters(m, question);
11680 question->TargetQID =
11682 (question->Target.type || Question_uDNS(question)) ? mDNS_NewMessageID(m) :
11685 debugf("mDNS_StartQuery_internal: %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
11689 if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P)
11691 while (*q && *q != question)
11696 LogMsg("mDNS_StartQuery_internal: Error! Tried to add a question %##s (%s) %p that's already in the active list",
11697 question->qname.c, DNSTypeName(question->qtype), question);
11700 *q = question;
11703 // Intialize the question. The only ordering constraint we have today is that
11708 purge = InitCommonState(m, question);
11709 InitWABState(question);
11710 InitLLQState(question);
11711 InitDNSSECProxyState(m, question);
11715 // question.
11716 question->DuplicateOf = FindDuplicateQuestion(m, question);
11717 if (question->DuplicateOf)
11718 question->AuthInfo = question->DuplicateOf->AuthInfo;
11720 if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P)
11723 m->NewLocalOnlyQuestions = question;
11728 m->NewQuestions = question;
11730 // If the question's id is non-zero, then it's Wide Area
11733 // NS, etc.) and if we haven't finished setting up our own question and setting
11735 // this routine with the question list data structures in an inconsistent state.
11736 if (!mDNSOpaque16IsZero(question->TargetQID))
11738 FinalizeUnicastQuestion(m, question, purge);
11744 LogInfo("mDNS_StartQuery_internal: Purging for %##s", question->qname.c);
11745 mDNS_PurgeForQuestion(m, question);
11756 debugf("CancelGetZoneData %##s (%s)", nta->question.qname.c, DNSTypeName(nta->question.qtype));
11757 // This function may be called anytime to free the zone information.The question may or may not have stopped.
11760 if (nta->question.ThisQInterval != -1)
11762 mDNS_StopQuery_internal(m, &nta->question);
11763 if (nta->question.ThisQInterval != -1)
11764 LogMsg("CancelGetZoneData: Question %##s (%s) ThisQInterval %d not -1", nta->question.qname.c, DNSTypeName(nta->question.qtype), nta->question.ThisQInterval);
11769 mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const question)
11771 const mDNSu32 slot = HashSlot(&question->qname);
11772 CacheGroup *cg = CacheGroupForName(m, slot, question->qnamehash, &question->qname);
11776 //LogInfo("mDNS_StopQuery_internal %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
11778 if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P) qp = &m->LocalOnlyQuestions;
11779 while (*qp && *qp != question) qp=&(*qp)->next;
11784 if (question->ThisQInterval >= 0) // Only log error message if the query was supposed to be active
11787 question->qname.c, DNSTypeName(question->qtype));
11794 // Take care to cut question from list *before* calling UpdateQuestionDuplicates
11795 UpdateQuestionDuplicates(m, question);
11797 question->ThisQInterval = -1;
11799 // If there are any cache records referencing this as their active question, then see if there is any
11800 // other question that is also referencing them, else their CRActiveQuestion needs to get set to NULL.
11803 if (rr->CRActiveQuestion == question)
11812 debugf("mDNS_StopQuery_internal: Updating CRActiveQuestion to %p for cache record %s, Original question CurrentAnswers %d, new question "
11813 "CurrentAnswers %d, SuppressQuery %d", q, CRDisplayString(m,rr), question->CurrentAnswers, q->CurrentAnswers, q->SuppressQuery);
11819 // If we just deleted the question that CacheRecordAdd() or CacheRecordRmv() is about to look at,
11820 // bump its pointer forward one question.
11821 if (m->CurrentQuestion == question)
11823 debugf("mDNS_StopQuery_internal: Just deleted the currently active question: %##s (%s)",
11824 question->qname.c, DNSTypeName(question->qtype));
11825 m->CurrentQuestion = question->next;
11828 if (m->NewQuestions == question)
11830 debugf("mDNS_StopQuery_internal: Just deleted a new question that wasn't even answered yet: %##s (%s)",
11831 question->qname.c, DNSTypeName(question->qtype));
11832 m->NewQuestions = question->next;
11835 if (m->NewLocalOnlyQuestions == question) m->NewLocalOnlyQuestions = question->next;
11837 if (m->RestartQuestion == question)
11839 LogMsg("mDNS_StopQuery_internal: Just deleted the current restart question: %##s (%s)",
11840 question->qname.c, DNSTypeName(question->qtype));
11841 m->RestartQuestion = question->next;
11844 if (m->ValidationQuestion == question)
11846 LogInfo("mDNS_StopQuery_internal: Just deleted the current Validation question: %##s (%s)",
11847 question->qname.c, DNSTypeName(question->qtype));
11848 m->ValidationQuestion = question->next;
11851 // Take care not to trash question->next until *after* we've updated m->CurrentQuestion and m->NewQuestions
11852 question->next = mDNSNULL;
11854 // LogMsg("mDNS_StopQuery_internal: Question %##s (%s) removed", question->qname.c, DNSTypeName(question->qtype));
11857 // Must not do this until last, because there's a good chance the GetZoneData question is the next in the list,
11858 // so if we delete it earlier in this routine, we could find that our "question->next" pointer above is already
11861 if (question->tcp) { DisposeTCPConn(question->tcp); question->tcp = mDNSNULL; }
11862 if (question->LocalSocket) { mDNSPlatformUDPClose(question->LocalSocket); question->LocalSocket = mDNSNULL; }
11863 if (!mDNSOpaque16IsZero(question->TargetQID) && question->LongLived)
11884 if (question->state == LLQ_Established)
11886 question->ReqLease = 0;
11887 sendLLQRefresh(m, question);
11889 // We clear the tcp->question backpointer so that when the TCP connection completes, it doesn't
11890 // crash trying to access our cancelled question, but we don't cancel the TCP operation itself --
11892 if (question->tcp)
11894 question->tcp->question = mDNSNULL;
11895 question->tcp = mDNSNULL;
11903 if (question->nta) { CancelGetZoneData(m, question->nta); question->nta = mDNSNULL; }
11905 if (question->ValidationRequired && question->DNSSECAuthInfo)
11907 LogInfo("mDNS_StopQuery_internal: freeing DNSSECAuthInfo %##s", question->qname.c);
11908 question->DAIFreeCallback(m, question->DNSSECAuthInfo);
11909 question->DNSSECAuthInfo = mDNSNULL;
11911 if (question->AnonInfo)
11913 FreeAnonInfo(question->AnonInfo);
11914 question->AnonInfo = mDNSNULL;
11920 mDNSexport mStatus mDNS_StartQuery(mDNS *const m, DNSQuestion *const question)
11924 status = mDNS_StartQuery_internal(m, question);
11929 mDNSexport mStatus mDNS_StopQuery(mDNS *const m, DNSQuestion *const question)
11933 status = mDNS_StopQuery_internal(m, question);
11939 // Specifically, question callbacks invoked as a result of this call cannot themselves make API calls.
11942 mDNSexport mStatus mDNS_StopQueryWithRemoves(mDNS *const m, DNSQuestion *const question)
11948 // Check if question is new -- don't want to give remove events for a question we haven't even answered yet
11949 for (qq = m->NewQuestions; qq; qq=qq->next) if (qq == question) break;
11951 status = mDNS_StopQuery_internal(m, question);
11955 const mDNSu32 slot = HashSlot(&question->qname);
11956 CacheGroup *const cg = CacheGroupForName(m, slot, question->qnamehash, &question->qname);
11957 LogInfo("Generating terminal removes for %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
11959 if (rr->resrec.RecordType != kDNSRecordTypePacketNegative && SameNameRecordAnswersQuestion(&rr->resrec, question))
11962 if (question->QuestionCallback)
11963 question->QuestionCallback(m, question, &rr->resrec, QC_rmv);
11993 mDNSlocal mStatus mDNS_StartBrowse_internal(mDNS *const m, DNSQuestion *const question,
11999 question->InterfaceID = InterfaceID;
12000 question->flags = flags;
12001 question->Target = zeroAddr;
12002 question->qtype = kDNSType_PTR;
12003 question->qclass = kDNSClass_IN;
12004 question->LongLived = mDNStrue;
12005 question->ExpectUnique = mDNSfalse;
12006 question->ForceMCast = ForceMCast;
12007 question->ReturnIntermed = mDNSfalse;
12008 question->SuppressUnusable = mDNSfalse;
12009 question->DenyOnCellInterface = mDNSfalse;
12010 question->DenyOnExpInterface = mDNSfalse;
12011 question->SearchListIndex = 0;
12012 question->AppendSearchDomains = 0;
12013 question->RetryWithSearchDomains = mDNSfalse;
12014 question->TimeoutQuestion = 0;
12015 question->WakeOnResolve = 0;
12016 question->UseBackgroundTrafficClass = useBackgroundTrafficClass;
12017 question->ValidationRequired = 0;
12018 question->ValidatingResponse = 0;
12019 question->ProxyQuestion = 0;
12020 question->qnameOrig = mDNSNULL;
12021 question->AnonInfo = mDNSNULL;
12022 question->QuestionCallback = Callback;
12023 question->QuestionContext = Context;
12025 if (!ConstructServiceName(&question->qname, mDNSNULL, srv, domain))
12030 question->AnonInfo = AllocateAnonInfo(&question->qname, anondata, mDNSPlatformStrLen(anondata), mDNSNULL);
12031 if (!question->AnonInfo)
12035 return(mDNS_StartQuery_internal(m, question));
12038 mDNSexport mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question,
12046 status = mDNS_StartBrowse_internal(m, question, srv, domain, anondata, InterfaceID, flags, ForceMCast, useBackgroundTrafficClass, Callback, Context);
12059 mDNSlocal void FoundServiceInfoSRV(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
12061 ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
12120 mDNSlocal void FoundServiceInfoTXT(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
12122 ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
12145 mDNSlocal void FoundServiceInfo(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
12147 ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
12195 query->qSRV.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
12223 query->qTXT.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
12251 query->qAv4.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
12279 query->qAv6.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
12341 mDNSexport mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, mDNS_DomainType DomainType, const domainname *dom,
12344 question->InterfaceID = InterfaceID;
12345 question->flags = 0;
12346 question->Target = zeroAddr;
12347 question->qtype = kDNSType_PTR;
12348 question->qclass = kDNSClass_IN;
12349 question->LongLived = mDNSfalse;
12350 question->ExpectUnique = mDNSfalse;
12351 question->ForceMCast = mDNSfalse;
12352 question->ReturnIntermed = mDNSfalse;
12353 question->SuppressUnusable = mDNSfalse;
12354 question->DenyOnCellInterface = mDNSfalse;
12355 question->DenyOnExpInterface = mDNSfalse;
12356 question->SearchListIndex = 0;
12357 question->AppendSearchDomains = 0;
12358 question->RetryWithSearchDomains = mDNSfalse;
12359 question->TimeoutQuestion = 0;
12360 question->WakeOnResolve = 0;
12361 question->UseBackgroundTrafficClass = mDNSfalse;
12362 question->ValidationRequired = 0;
12363 question->ValidatingResponse = 0;
12364 question->ProxyQuestion = 0;
12365 question->qnameOrig = mDNSNULL;
12366 question->AnonInfo = mDNSNULL;
12367 question->pid = mDNSPlatformGetPID();
12368 question->QuestionCallback = Callback;
12369 question->QuestionContext = Context;
12371 if (!MakeDomainNameFromDNSNameString(&question->qname, mDNS_DomainTypeNames[DomainType])) return(mStatus_BadParamErr);
12373 if (!AppendDomainName(&question->qname, dom)) return(mStatus_BadParamErr);
12374 return(mDNS_StartQuery(m, question));
12458 // the record list and/or question list.
12744 // We initialize ThisQInterval to -1 indicating that the question has not been started
12745 // yet. If the question (browse) is started later during interface registration, it will
12747 // question has been stopped or not before initializing it to -1 because we need to
12916 { // then reactivate this question
12968 // the record list and/or question list.
13474 // which may change the record list and/or question list.
13660 // (i) as an indication that the host in question has not gone to sleep yet (so we should delay beginning to proxy for it) or
14462 // For DNSSEC question, we need the DNSSEC records also. If the cache does not
14463 // have the DNSSEC records, we need to re-issue the question with EDNS0/DO bit set.
14464 // Just re-issuing the question for RRSIGs does not work in practice as the response
14465 // may not contain the RRSIGs whose typeCovered field matches the question's qtype.
14469 // RRSIGs and if we have not already issued the question with EDNS0/DO bit set, purge
14493 // Check for a positive unicast response to the question but with qtype
14496 DNSQuestion question;
14501 // Create an identical question but with qtype
14502 mDNS_SetupQuestion(&question, q->InterfaceID, &q->qname, qtype, mDNSNULL, mDNSNULL);
14503 question.qDNSServer = q->qDNSServer;
14508 SameNameRecordAnswersQuestion(&rp->resrec, &question))
14524 LogMsg("DNSServerChangeForQuestion: ERROR: Called for duplicate question %##s", q->qname.c);
14527 // of events for all of them are consistent. Duplicates for a question are always inserted
14605 // questions here. Neither question nor cache point to mcast resolvers. Questions
14631 // - A non-scoped question picks DNSServer X, creates a cache entry with X. If a new resolver gets added later that
14632 // is a better match, we pick the new DNSServer for the question and activate the unicast query. We may or may not
14637 // we don't update the cache record's DNSServer pointer to match the question's DNSSever, as they both point to
14643 // - A non-scoped question picks DNSServer X, creates a cache entry with X. If the resolver gets removed later, we will
14644 // pick a new DNSServer for the question which may or may not be NULL and set the cache record's pointer to the same
14645 // as in question's qDNSServer if the cache record is not flushed. If there is no active question, it will be set to NULL.
14649 // non-scoped question and vice versa.
14675 // If DNS Server for this question has changed, reactivate it
14676 LogInfo("uDNS_SetupDNSConfig: Updating DNS Server from %#a:%d (%##s) to %#a:%d (%##s) for question %##s (%s) (scope:%p)",
14727 debugf("uDNS_SetupDNSConfig: Not Updating DNS server question %p %##s (%s) DNS server %#a:%d %p %d",
14743 // change affected the question. That should take care of updating the cache. But
14744 // what if there is no active question at this point when the DNS server change
14746 // them, a new question after the DNS server change could pick up these stale
14752 // active question's InterfaceID/ServiceID for looking up the right DNS server.
14756 // DNS servers or no matching DNS servers for this question. In either case,
14767 // want any new questions to pick this old value. If there is no active question,
14768 // we can't possibly re-confirm, so purge in that case. If it is a DNSSEC question,
14792 // different DNS servers can give different answers to the same question.
14799 // If we don't have an active question for this cache record, neither Purge can
14804 // If there is an active question, point to its DNSServer as long as it does not point to the
14814 LogMsg("uDNS_SetupDNSConfig: ERROR!! Cache Record %s Active question %##s (%s) (scope:%p) poining to DNSServer Address %#a"
14822 LogInfo("uDNS_SetupDNSConfig: Cache Record %s, Active question %##s (%s) (scope:%p), pointing to DNSServer %#a (to be deleted),"
14823 " resetting to question's DNSServer Address %#a", CRDisplayString(m, cr), qptr->qname.c, DNSTypeName(qptr->qtype),
14830 LogInfo("uDNS_SetupDNSConfig: Cache Record %##s has no Active question, Record's DNSServer Address %#a, Server to be deleted %#a",