Lines Matching defs:question

140 // A, AAAA , CNAME, or PTR.  The caller should answer the question with this record and not send out 
141 // the question on the wire if LocalOnlyRecordAnswersQuestion() also returns true.
163 // Depending on whether this is a multicast or unicast question we want to set either:
420 LogInfo("GenerateNegativeResponse: Generating negative response for question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
426 // b) Append search domains and retry the question
428 // The question may not have set Intermediates in which case we don't deliver negative responses. So, to force
431 if (m->CurrentQuestion == q) { q->ThisQInterval = 0; } // Deactivate this question
432 // Don't touch the question after this
455 // both A and AAAA question and while answering it we don't want to throw
475 // A and B, and when we stop question A, UpdateQuestionDuplicates copies the value of CNAMEReferrals
477 // the target name is still the same), and then when we stop question B, UpdateQuestionDuplicates
480 // those cases the newly re-appended question A has a different target name and therefore cannot be
481 // a duplicate of any other question ('B') which was itself a duplicate of the previous question A.
537 // We have a message waiting and that should answer this question.
547 // Note: All the callers should use the m->CurrentQuestion to see if the question is still valid or not
585 // The callback above could have caused the question to stop. Detect that
626 // our main question list, delivering answers to mDNSInterface_Any questions as appropriate,
694 // Number of wakeups we send if WakeOnResolve is set in the question
1567 // Note: mDNS_Deregister_internal can call a user callback, which may change the record list and/or question list.
1684 // The AnswerAllLocalQuestionsWithLocalAuthRecord routine walks the question list invoking client callbacks, using the "m->CurrentQuestion"
1685 // mechanism to cope with the client callback modifying the question list while that's happening.
1739 // We may want to consider changing this code so that we generate local-only question "rmv"
2046 // which may change the record list and/or question list.
2372 // the record list and/or question list.
2934 // If we have an active question, then see if we want to schedule a refresher query for this record.
2975 // BuildQuestion puts a question into a DNS Query packet and if successful, updates the value of queryptr.
2988 debugf("BuildQuestion: No more space in this packet for question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
3004 SameNameRecordAnswersQuestion(&rr->resrec, q) && // which answers our question
3018 // If we're trying to put more than one question in this packet, and it doesn't fit
3019 // then undo that last question and try again next time
3023 debugf("BuildQuestion: Retracting question %##s (%s) new forecast total %d, total questions %d",
3040 SameNameRecordAnswersQuestion(&rr->resrec, q)) // which answers our question
3216 LogMsg("mDNSSendWakeOnResolve: ERROR!! Invalid InterfaceID %p for question %##s", InterfaceID, q->qname.c);
3275 SameNameRecordAnswersQuestion(&rr->resrec, q) && // which answers our question
3290 // 1. The Question Section contains the question
3348 // Indicate that this question was marked for sending
3393 q->SendQNow = mDNSInterfaceMark; // Mark this question for sending on all interfaces
3399 // m->CurrentQuestion point to the right question
3404 LogInfo("SendQueries question loop 1: Skipping NewQuestion %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
3414 // 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.
3426 // If we have reached the answer threshold for this question,
3444 // Mark this question for sending on all interfaces
3479 // If we recorded a duplicate suppression for this question less than half an interval ago,
3604 debugf("SendQueries: %s question for %##s (%s) at %d forecast total %d",
3614 // If we're suppressing this question, or we successfully put it, update its SendQNow state
3618 // We successfully added the question to the packet. Make sure that
3630 debugf("SendQueries: marking for question %##s, Suppress %d", q->qname.c, Suppress);
3640 // use background traffic class if any included question requires it
3671 // Put our known answer list (either new one from this question or questions, or remainder of old one from last time)
3688 // If we ran out of space and we have more than one question in the packet, that's an error --
3689 // we shouldn't have put more than one question if there was a risk of us running out of space.
3769 LogMsg("SendQueries: Should not have more than one question (%d) in a truncated packet", m->omsg.h.numQuestions);
3831 for (x = m->NewQuestions; x; x=x->next) if (x == q) break; // Check if this question is a NewQuestion
3832 LogInfo("SendQueries: No active interface %d to send %s question: %d %##s (%s)",
3883 // Whenever a question is answered, reset its state so that we don't query
3884 // the network repeatedly. This happens first time when we answer the question and
3899 // Note: AnswerCurrentQuestionWithResourceRecord can call a user callback, which may change the record list and/or question list.
3901 // In fact, to enforce this, the routine will *only* answer the question currently pointed to by m->CurrentQuestion,
3902 // which will be auto-advanced (possibly to NULL) if the client callback cancels the question.
3911 // When the response for the question was validated, the entire rrset was validated. If we deliver
4007 // for the purpose of retrying search domains/timeout OR the question is suppressed
4025 // If this is an "Add" operation and this question needs validation, validate the response.
4054 // don't follow them. If it is a ValidationRequired question, wait for the CNAME to be validated
4098 // 2) A new question is about to be answered and the caller needs to know whether it's
4099 // scheduling should be delayed so that the question is not answered with this record.
4101 // (new entry), a single ADD can be delivered by delaying the scheduling of the question
4113 // Also, if there is already an active question we don't try to optimize as purging the cache
4114 // would end up delivering RMV for the active question and hence we avoid that.
4141 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
4145 // which may change the record list and/or question list.
4158 // If this question is one that's actively sending queries, and it's received ten answers within one
4177 verbosedebugf("CacheRecordAdd %p %##s (%s) %lu %#a:%d question %p", rr, rr->resrec.name->c,
4219 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
4221 // but we don't have any place to cache it. We'll deliver question 'add' events now, but we won't have any
4225 // which may change the record list and/or question list.
4247 // Note that CacheRecordRmv is *only* called for records that are referenced by at least one active question.
4249 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
4253 // which may change the record list and/or question list.
4267 // When a question enters suppressed state, we generate RMV events and generate a negative
4268 // response. A cache may be present that answers this question e.g., cache entry generated
4269 // before the question became suppressed. We need to skip the suppressed questions here as
4290 // If we have dropped below the answer threshold for this mDNS question,
4443 // before we pick a new DNS server. As the question interval is set to MaxQuestionInterval, we may
4444 // not send out a query anytime soon. Hence, we need to reset the question interval. If this is
4471 else // else trigger our question to go out now
4496 // If "CheckOnly" is set to "true", the question won't be answered but just check to see if there is an answer and
4499 // If "CheckOnly" is set to "false", the question will be answered if there is a LocalOnly/P2P record and
4520 // If the question is mDNSInterface_LocalOnly, all records local to the machine should be used
4532 LogInfo("AnswerQuestionWithLORecord: question %##s (%s) answered by %s", q->qname.c, DNSTypeName(q->qtype),
4559 // no local records that could possibly answer this question. As we did not check the NewLocalRecords, we
4560 // need to just peek at them to see whether it will answer this question. If it would answer, pretend
4562 // when we add new /etc/hosts entries and restart the question. It is a new question and also a new record.
4604 DNSQuestion *const q = m->NewQuestions; // Grab the question we're going to answer
4615 // then CheckCacheExpiration may give this question add/remove callbacks, and it's not yet ready for that.
4618 // client callbacks, which may delete their own or any other question. Our mechanism for detecting
4619 // whether our current m->NewQuestions question got deleted by one of these callbacks is to store the
4622 // advanced it), that means the question was deleted, so we no longer need to worry about answering
4624 // values we computed for slot and cg are now stale and relate to a question that no longer exists).
4629 // deleting a question, so luckily we have an easy alternative way of detecting if our question got deleted.
4632 // This should be safe, because calling the client's question callback may cause the
4633 // question list to be modified, but should not ever cause the rrcache list to be modified.
4634 // If the client's question callback deletes the question, then m->CurrentQuestion will
4640 m->CurrentQuestion = q; // Indicate which question we're answering, so we'll know if it gets deleted
4648 // Don't touch the question if it has been stopped already
4664 // If we are not supposed to answer this question, generate a negative response.
4665 // Temporarily suspend the SuppressQuery so that AnswerCurrentQuestionWithResourceRecord can answer the question
4667 // If it is a question trying to validate some response, it already checked the cache for a response. If it still
4668 // reissues a question it means it could not find the RRSIGs. So, we need to bypass the cache check and send
4669 // the question out.
4707 // Neither a local record nor a cache entry could answer this question. If this question need to be retried
4719 // Note: When a query gets suppressed or retried with search domains, we de-activate the question.
4737 // answers for this question until *after* its scheduled transmission time, in which case
4753 DNSQuestion *q = m->NewLocalOnlyQuestions; // Grab the question we're going to answer
4761 m->CurrentQuestion = q; // Indicate which question we're answering, so we'll know if it gets deleted
4766 // 1. First walk the LocalOnly records answering the LocalOnly question
5046 LogInfo("TimeoutQuestions: question %p %##s timed out, time %d", q, q->qname.c, m->timenow - q->StopTime);
5058 // depends on having m->CurrentQuestion point to the right question
5381 // 1. When a new question is created
5385 // In cases 2 and 3 we do want to cause the question to be resent immediately (ScheduleImmediately is true)
5386 mDNSlocal void ActivateUnicastQuery(mDNS *const m, DNSQuestion *const question, mDNSBool ScheduleImmediately)
5398 if (RRTypeIsAddressType(question->qtype) && PrivateQuery(question) &&
5399 !SameDomainLabel(question->qname.c, (const mDNSu8 *)"\x0c_autotunnel6")&& question->QuestionCallback != AutoTunnelCallback)
5401 question->NoAnswer = NoAnswer_Suspended;
5402 AddNewClientTunnel(m, question);
5407 if (!question->DuplicateOf)
5410 question->qname.c, DNSTypeName(question->qtype), PrivateQuery(question) ? " (Private)" : "", ScheduleImmediately ? " ScheduleImmediately" : "");
5411 question->CNAMEReferrals = 0;
5412 if (question->nta) { CancelGetZoneData(m, question->nta); question->nta = mDNSNULL; }
5413 if (question->LongLived)
5415 question->state = LLQ_InitialRequest;
5416 question->id = zeroOpaque64;
5417 question->servPort = zeroIPPort;
5418 if (question->tcp) { DisposeTCPConn(question->tcp); question->tcp = mDNSNULL; }
5420 // If the question has local answers, then we don't want answers from outside
5421 if (ScheduleImmediately && !QuestionHasLocalAnswers(m, question))
5423 question->ThisQInterval = InitialQuestionInterval;
5424 question->LastQTime = m->timenow - question->ThisQInterval;
5425 SetNextQueryTime(m, question);
5443 // we are going to stop the question. Hence we need to deliver the RMV event before we
5444 // stop the question.
5447 // application callback can potentially stop the current question (detected by CurrentQuestion) or
5448 // *any* other question which could be the next one that we may process here. RestartQuestion
5449 // points to the "next" question which will be automatically advanced in mDNS_StopQuery_internal
5450 // if the "next" question is stopped while the CurrentQuestion is stopped
5462 // question) through their "nta" pointer. Normally when the original query stops, it stops the
5463 // GetZoneData question and also frees the memory (See CancelGetZoneData). If we stop the GetZoneData
5464 // question followed by the original query that refers to this GetZoneData question, we will end up
5465 // freeing the GetZoneData question and then start the "freed" question at the end.
5471 // debug stuff, we just try to find the referencing question and don't do much with it
5474 if (q == &refq->nta->question)
5506 LogInfo("mDNSCoreRestartAddressQueries: Stop question %p %##s (%s), AppendSearchDomains %d, qnameOrig %p", q,
5534 LogInfo("mDNSCoreRestartAddressQueries: Start question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
5562 // restart question if it's multicast and currently active
5567 q->ThisQInterval = InitialQuestionInterval; // MUST be > zero for an active question
6152 mDNSlocal void NetWakeResolve(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
6154 NetworkInterfaceInfo *intf = (NetworkInterfaceInfo *)question->QuestionContext;
6155 int sps = (int)(question - intf->NetWakeResolve);
6160 if (answer->rrtype != question->qtype) return; // Don't care about CNAMEs
6167 mDNS_StopQuery(m, question);
6169 AssignDomainName(&question->qname, &answer->rdata->u.srv.target);
6170 question->qtype = kDNSType_A;
6171 mDNS_StartQuery(m, question);
6176 mDNS_StopQuery(m, question);
6177 question->ThisQInterval = -1;
6187 mDNS_StopQuery(m, question);
6188 LogSPS("NetWakeResolve: SPS %d %##s has no IPv4 address, will try IPv6 instead", sps, question->qname.c);
6189 question->qtype = kDNSType_AAAA;
6190 mDNS_StartQuery(m, question);
6195 mDNS_StopQuery(m, question);
6196 question->ThisQInterval = -1;
6887 for (i=0; i<query->h.numQuestions; i++) // For each question...
6890 ptr = getQuestion(query, ptr, end, InterfaceID, &q); // get the question...
6895 if (rr->NR_AnswerTo == ptr) // If we're going to generate a record answering this question
6896 { // then put the question in the question section
6899 break; // break out of the ResponseRecords loop, and go on to the next question
7045 // the record list and/or question list.
7275 for (i=0; i<query->h.numQuestions; i++) // For each question...
7281 ptr = getQuestion(query, ptr, end, InterfaceID, &pktq); // get the question...
7307 // can result in user callbacks which may change the record list and/or question list.
7328 // As we have verified this question to be part of the same subset,
7347 // We only mark this question for sending if it is at least one second since the last time we multicast it
7359 // If we don't have any answers for this question, but we do own another record with the same name,
7373 // If we couldn't answer this question, someone else might be able to,
7382 // We only do the following accelerated cache expiration and duplicate question suppression processing
7420 // Check if this question is the same as any of mine.
7427 // For anonymous question, the duplicate suppressesion should happen if the
7428 // question belongs in the same group. As the group is expected to be
7846 mDNSlocal DNSQuestion *ExpectingUnicastResponseForQuestion(const mDNS *const m, const mDNSIPPort port, const mDNSOpaque16 id, const DNSQuestion *const question, mDNSBool tcp)
7854 q->qtype == question->qtype &&
7855 q->qclass == question->qclass &&
7856 q->qnamehash == question->qnamehash &&
7857 SameDomainName(&q->qname, &question->qname))
7949 // if it finds a matching question with this record, it bumps up the counters like
8069 // When the response does not match the question directly, we still want to cache them sometimes. The current response is
8082 // match the question and we already created a cache entry in the previous pass of this loop. Now when we process
8083 // the A record, it does not match the question because the record name here is the CNAME. Hence we try to
8094 // Either the question requires validation or we are validating a response with DNSSEC in which case
8107 // We cache RRSIGS if it covers the question type or NSEC. If it covers a NSEC,
8122 LogInfo("IsResponseAcceptable: Accepting RRSIG %s matches question type %s", CRDisplayString(m, newcr),
8179 // information to ValidatingResponse question to indicate the DNSSEC status to the application
8197 LogMsg("mDNSCoreReceiveNoDNSSECAnswers: ERROR!! qptr %##s (%s) Duplicate question matching response", qptr->qname.c, DNSTypeName(qptr->qtype));
8200 // question. If we called the callback on the original question, it could stop and
8201 // a duplicate question would become the original question.
8209 LogInfo("mDNSCoreReceiveNoDNSSECAnswers: qptr %##s (%s) Duplicate question found", q->qname.c, DNSTypeName(q->qtype));
8211 LogMsg("mDNSCoreReceiveNoDNSSECAnswers: ERROR!! qptr %##s (%s) Duplicate question not ValidatingResponse", q->qname.c, DNSTypeName(q->qtype));
8259 // By suppressing negative responses, it might take longer to timeout a .local question as it might be expecting a
8363 // When we created the cache for the first time and answered the question, the question's
8367 // we should reset its question interval here to MaxQuestionInterval.
8599 // record in the list that answers the question so that it can be used for validation
8601 // that would answer the question. It is possible that we might cache additional things
8602 // e.g., MX question might cache A records also, and we want to cache the NSEC on
8603 // the record that answers the question.
8610 // We have to reset the question interval to MaxQuestionInterval so that we don't keep
8614 // configuration changed, without flushing the cache, we reset the question interval here.
8712 // the record list and/or question list.
8798 // answer questions in this packet's question section, but which aren't tagged with this packet's
8809 // Remember the unicast question that we found, which we use to make caching
8837 LogInfo("mDNSCoreReceiveResponse: CRDNSSECQuestion set for record %s, question %##s (%s)", CRDisplayString(m, rr),
8849 // req_DO to false here, the next retransmission for this question will turn off validation
8897 // to any specific question -- any code reading records from the cache needs to make that determination for itself.)
8961 // queries to get ADD/RMV events. To lookup the question, we can't use
8963 // has already matched the question using the 64 bit Id in the packet and we use that here.
8967 // If this is a DNSSEC question that is also LongLived, don't accept records from the
8990 // on the "id" and "source port", then this response answers the question and assume the response
9006 // If we can't find a matching question, we need to see whether we have seen records earlier that matched
9007 // the question. The code below does that. So, make this record unacceptable for now
9010 debugf("mDNSCoreReceiveResponse: Can't find question for record name %##s", m->rec.r.resrec.name->c);
9216 // Remember whether we created a cache record in response to a DNSSEC question.
9217 // This helps DNSSEC code not to reissue the question to fetch the DNSSEC records.
9221 LogInfo("mDNSCoreReceiveResponse: CRDNSSECQuestion set for new record %s, question %##s (%s)", CRDisplayString(m, rr),
9394 // If we had a unicast question for this response with at least one positive answer and we
9438 // ValidatingResponse question waiting for this response, give a hint that no RRSIGs
10373 // is suppressed. If it is not suppressed, we do try all the DNS servers for valid answers like any other question.
10374 // The main reason for this design is that cache entries point to a *single* question and that question is responsible
10375 // for keeping the cache fresh as long as it is active. Having multiple active question for a single cache entry
10379 // If IsLLQ(Q) is true, it means the question is both:
10386 mDNSlocal DNSQuestion *FindDuplicateQuestion(const mDNS *const m, const DNSQuestion *const question)
10389 // Note: A question can only be marked as a duplicate of one that occurs *earlier* in the list.
10391 // Accordingly, we break out of the loop when we get to 'question', because there's no point searching
10393 for (q = m->Questions; q && q != question; q=q->next) // Scan our list for another question
10394 if (q->InterfaceID == question->InterfaceID && // with the same InterfaceID,
10395 SameQTarget(q, question) && // and same unicast/multicast target settings
10396 q->qtype == question->qtype && // type,
10397 q->qclass == question->qclass && // class,
10398 IsLLQ(q) == IsLLQ(question) && // and long-lived status matches
10399 (!q->AuthInfo || question->AuthInfo) && // to avoid deadlock, don't make public query dup of a private one
10400 (q->AnonInfo == question->AnonInfo) && // Anonymous query not a dup of normal query
10401 (q->SuppressQuery == question->SuppressQuery) && // Questions that are suppressed/not suppressed
10402 (q->ValidationRequired == question->ValidationRequired) && // Questions that require DNSSEC validation
10403 (q->ValidatingResponse == question->ValidatingResponse) && // Questions that are validating responses using DNSSEC
10404 (q->DisallowPID == question->DisallowPID) && // Disallowing a PID should not affect a PID that is allowed
10405 (q->BrowseThreshold == question->BrowseThreshold) && // browse thresholds must match
10406 q->qnamehash == question->qnamehash &&
10407 (IsAWDLIncluded(q) == IsAWDLIncluded(question)) && // Inclusion of AWDL interface must match
10408 SameDomainName(&q->qname, &question->qname)) // and name
10413 // This is called after a question is deleted, in case other identical questions were being suppressed as duplicates
10414 mDNSlocal void UpdateQuestionDuplicates(mDNS *const m, DNSQuestion *const question)
10419 // This is referring to some other question as duplicate. No other question can refer to this
10420 // question as a duplicate.
10421 if (question->DuplicateOf)
10423 LogInfo("UpdateQuestionDuplicates: question %p %##s (%s) duplicate of %p %##s (%s)",
10424 question, question->qname.c, DNSTypeName(question->qtype),
10425 question->DuplicateOf, question->DuplicateOf->qname.c, DNSTypeName(question->DuplicateOf->qtype));
10430 if (q->DuplicateOf == question) // To see if any questions were referencing this as their duplicate
10437 // then inherit the state from the question that's going away
10438 q->LastQTime = question->LastQTime;
10439 q->ThisQInterval = question->ThisQInterval;
10440 q->ExpectUnicastResp = question->ExpectUnicastResp;
10441 q->LastAnswerPktNum = question->LastAnswerPktNum;
10442 q->RecentAnswerPkts = question->RecentAnswerPkts;
10443 q->RequestUnicast = question->RequestUnicast;
10444 q->LastQTxTime = question->LastQTxTime;
10445 q->CNAMEReferrals = question->CNAMEReferrals;
10446 q->nta = question->nta;
10447 q->servAddr = question->servAddr;
10448 q->servPort = question->servPort;
10449 q->qDNSServer = question->qDNSServer;
10450 q->validDNSServers = question->validDNSServers;
10451 q->unansweredQueries = question->unansweredQueries;
10452 q->noServerResponse = question->noServerResponse;
10453 q->triedAllServersOnce = question->triedAllServersOnce;
10455 q->TargetQID = question->TargetQID;
10461 q->LocalSocket = question->LocalSocket;
10463 q->state = question->state;
10464 // q->tcp = question->tcp;
10465 q->ReqLease = question->ReqLease;
10466 q->expire = question->expire;
10467 q->ntries = question->ntries;
10468 q->id = question->id;
10470 question->LocalSocket = mDNSNULL;
10471 question->nta = mDNSNULL; // If we've got a GetZoneData in progress, transfer it to the newly active question
10472 // question->tcp = mDNSNULL;
10484 if (question->tcp) LogInfo("UpdateQuestionDuplicates did not transfer tcp pointer");
10486 if (question->state == LLQ_Established)
10489 question->state = 0; // Must zero question->state, or mDNS_StopQuery_internal will clean up and cancel our LLQ from the server
10595 mDNSlocal mDNSu32 GetTimeoutForMcastQuestion(mDNS *m, DNSQuestion *question)
10598 int bestmatchlen = -1, namecount = CountLabels(&question->qname);
10604 bettermatch = BetterMatchForName(&question->qname, namecount, &curr->domain, currcount, bestmatchlen);
10613 LogInfo("GetTimeoutForMcastQuestion: question %##s curmatch %p, Timeout %d", question->qname.c, curmatch,
10628 if (CountLabels(qname) < 4) { debugf("DomainEnumQuery: question %##s, not enough labels", qname->c); return mDNSfalse; }
10667 // Note: InterfaceID is the InterfaceID of the question
10679 // The first condition in the "if" statement checks to see if both the question and the DNSServer are
10680 // unscoped. The question is unscoped only if InterfaceID is zero and ServiceID is -1.
10689 // unscoped question should not match scoped DNSServer (Refer to (1) above). The InterfaceID check
10692 // - DNSServer is scoped and InterfaceID is not NULL - the InterfaceID of the question and the DNSServer
10696 // If a question is scoped both to InterfaceID and ServiceID, the question will be scoped to InterfaceID.
10707 // Sets all the Valid DNS servers for a question
10708 mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
10710 int bestmatchlen = -1, namecount = CountLabels(&question->qname);
10717 question->validDNSServers = zeroOpaque64;
10718 DEQuery = DomainEnumQuery(&question->qname);
10745 if ((!DEQuery || !curr->cellIntf) && DNSServerMatch(curr, question->InterfaceID, question->ServiceID))
10747 bettermatch = BetterMatchForName(&question->qname, namecount, &curr->domain, currcount, bestmatchlen);
10759 question->validDNSServers = zeroOpaque64;
10762 debugf("SetValidDNSServers: question %##s Setting the bit for DNS server Address %#a (Domain %##s), Scoped:%d index %d,"
10763 " Timeout %d, interface %p", question->qname.c, &curr->addr, curr->domain.c, curr->scoped, index, curr->timeout,
10767 debugf("DomainEnumQuery: Question %##s, DNSServer %#a, cell %d", question->qname.c, &curr->addr, curr->cellIntf);
10768 bit_set_opaque64(question->validDNSServers, index);
10773 question->noServerResponse = 0;
10775 debugf("SetValidDNSServers: ValidDNSServer bits 0x%x%x for question %p %##s (%s)",
10776 question->validDNSServers.l[1], question->validDNSServers.l[0], question, question->qname.c, DNSTypeName(question->qtype));
10779 return ((question->ProxyQuestion || question->ValidatingResponse) ? DEFAULT_UDNSSEC_TIMEOUT : timeout ? timeout : DEFAULT_UDNS_TIMEOUT);
10820 // If there are multiple best servers for a given question, we will pick the first one
10831 // This happens when we initially walk all the DNS servers and set the validity bit on the question.
10885 // Look up a DNS Server for a question within its valid DNSServer bits
10886 mDNSexport DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question)
10890 mDNSInterfaceID InterfaceID = question->InterfaceID;
10891 const domainname *name = &question->qname;
10900 if (!mDNSOpaque64IsZero(&question->validDNSServers))
10902 curmatch = GetBestServer(m, name, InterfaceID, question->ServiceID, question->validDNSServers, &currindex, mDNSfalse);
10904 bit_clr_opaque64(question->validDNSServers, currindex);
10910 question, curmatch, &curmatch->addr, mDNSVal16(curmatch->port),
10912 InterfaceID, question->ServiceID, name, DNSTypeName(question->qtype));
10917 question, ifname ? ifname : "None", InterfaceID, question->ServiceID, name, DNSTypeName(question->qtype));
11030 // 1. If we find a LocalOnly or P2P record answering this question, then don't suppress it.
11043 // 2. If we find a local AuthRecord answering this question, then don't suppress it.
11066 // the question.
11071 LogInfo("ShouldSuppressQuery: Query not suppressed for %##s, qtype %s, Local question", q->qname.c, DNSTypeName(q->qtype));
11076 LogInfo("ShouldSuppressQuery: Query suppressed for %##s, qtype %s, Local question", q->qname.c, DNSTypeName(q->qtype));
11097 LogInfo("CacheRecordRmvEventsForCurrentQuestion: CacheRecord %s Suppressing RMV events for question %p %##s (%s), CRActiveQuestion %p, CurrentAnswers %d",
11104 LogInfo("CacheRecordRmvEventsForCurrentQuestion: Calling AnswerCurrentQuestionWithResourceRecord (RMV) for question %##s using resource record %s LocalAnswers %d",
11114 // If this was the active question for this cache entry, it was the one that was
11117 // when the cache entry is about to expire, we won't find an active question
11125 "Original question CurrentAnswers %d, new question CurrentAnswers %d, SuppressUnusable %d, SuppressQuery %d",
11137 mDNSlocal mDNSBool IsQuestionNew(mDNS *const m, DNSQuestion *question)
11141 if (q == question) return mDNStrue;
11186 // Returns false if the question got deleted while delivering the RMV events
11194 // If it is a new question, we have not delivered any ADD events yet. So, don't deliver RMV events.
11195 // If this question was answered using local auth records, then you can't deliver RMVs using cache
11203 else { LogInfo("CacheRecordRmvEventsForQuestion: Question %p %##s (%s) is a new question", q, q->qname.c, DNSTypeName(q->qtype)); }
11225 // question below, we need to deliver the RMV events so that the ADDs that will be delivered during
11235 // 1. Previously it was suppressed and now it is not suppressed, restart the question so
11236 // that it will start as a new question. Note that we can't just call ActivateUnicastQuery
11238 // this question if the cache entry did not change. Hence, we need to restart
11242 // so that we redo the duplicate checks in mDNS_StartQuery_internal. A SuppressUnusable question
11243 // is a duplicate of non-SuppressUnusable question if it is not suppressed (SuppressQuery is false).
11244 // A SuppressUnusable question is not a duplicate of non-SuppressUnusable question if it is suppressed
11245 // (SuppressQuery is true). The reason for this is that when a question is suppressed, we want an
11246 // immediate response and not want to be blocked behind a question that is querying DNS servers. When
11247 // the question is not suppressed, we don't want two active questions sending packets on the wire.
11248 // This affects both efficiency and also the current design where there is only one active question
11253 // If there are duplicate questions, calling stop inherits the values from another question on the list (which
11254 // will soon become the real question) including q->ThisQInterval which might be zero if it was
11260 LogInfo("SuppressStatusChanged: Stop question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
11279 // application callback can potentially stop the current question (detected by CurrentQuestion) or
11280 // *any* other question which could be the next one that we may process here. RestartQuestion
11281 // points to the "next" question which will be automatically advanced in mDNS_StopQuery_internal
11282 // if the "next" question is stopped while the CurrentQuestion is stopped
11299 // AnswerCurrentQuestionWithResourceRecord can answer the question
11309 LogInfo("CheckSuppressUnusableQuestions: Start question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
11330 LogMsg("RestartUnicastQuestions: ERROR!! Restart set for multicast question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
11341 LogInfo("RestartUnicastQuestions: Start question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
11349 mDNSlocal mStatus ValidateParameters(mDNS *const m, DNSQuestion *const question)
11352 if (question->Target.type && !ValidQuestionTarget(question))
11354 LogMsg("ValidateParameters: Warning! Target.type = %ld port = %u (Client forgot to initialize before calling mDNS_StartQuery? for question %##s)",
11355 question->Target.type, mDNSVal16(question->TargetPort), question->qname.c);
11356 question->Target.type = mDNSAddrType_None;
11359 // If no question->Target specified, clear TargetPort
11360 if (!question->Target.type)
11361 question->TargetPort = zeroIPPort;
11363 if (!ValidateDomainName(&question->qname))
11365 LogMsg("ValidateParameters: Attempt to start query with invalid qname %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
11369 // If this question is referencing a specific interface, verify it exists
11370 if (question->InterfaceID && question->InterfaceID != mDNSInterface_LocalOnly && question->InterfaceID != mDNSInterface_Unicast && question->InterfaceID != mDNSInterface_P2P)
11372 NetworkInterfaceInfo *intf = FirstInterfaceForID(m, question->InterfaceID);
11374 LogInfo("ValidateParameters: Note: InterfaceID %d for question %##s (%s) not currently found in active interface list",
11375 (uint32_t)question->InterfaceID, question->qname.c, DNSTypeName(question->qtype));
11383 mDNSlocal void InitDNSConfig(mDNS *const m, DNSQuestion *const question)
11386 question->qDNSServer = mDNSNULL;
11387 question->validDNSServers = zeroOpaque64;
11388 question->triedAllServersOnce = 0;
11389 question->noServerResponse = 0;
11390 question->StopTime = 0;
11392 mDNSPlatformMemZero(&question->metrics, sizeof(question->metrics));
11396 if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P)
11399 if (!mDNSOpaque16IsZero(question->TargetQID))
11401 mDNSu32 timeout = SetValidDNSServers(m, question);
11410 // it gets a full timeout value even if the original question times out earlier.
11411 if (question->TimeoutQuestion)
11413 question->StopTime = NonZeroTime(m->timenow + timeout * mDNSPlatformOneSecond);
11414 LogInfo("InitDNSConfig: Setting StopTime on question %p %##s (%s)", question, question->qname.c, DNSTypeName(question->qtype));
11417 question->qDNSServer = GetServerForQuestion(m, question);
11418 LogInfo("InitDNSConfig: question %p %##s (%s) Timeout %d, DNS Server %#a:%d",
11419 question, question->qname.c, DNSTypeName(question->qtype), timeout,
11420 question->qDNSServer ? &question->qDNSServer->addr : mDNSNULL,
11421 mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zp));
11425 if (question->TimeoutQuestion)
11426 question->StopTime = NonZeroTime(m->timenow + GetTimeoutForMcastQuestion(m, question) * mDNSPlatformOneSecond);
11429 if (question->StopTime)
11430 SetNextQueryStopTime(m, question);
11433 SetNextQueryTime(m,question);
11438 mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
11444 // Note: In the case where we already have the answer to this question in our cache, that may be all the client
11445 // wanted, and they may immediately cancel their question. In this case, sending an actual query on the wire would
11449 question->next = mDNSNULL;
11452 // the question list to check if ThisQInterval is negative which means the question has been
11453 // stopped and can't be on the list. The question is already on the list and ThisQInterval
11457 question->ThisQInterval = InitialQuestionInterval; // MUST be > zero for an active question
11458 question->qnamehash = DomainNameHashValue(&question->qname);
11459 question->DelayAnswering = CheckForSoonToExpireRecords(m, &question->qname, question->qnamehash, HashSlot(&question->qname), &purge);
11460 question->LastQTime = m->timenow;
11461 question->ExpectUnicastResp = 0;
11462 question->LastAnswerPktNum = m->PktNum;
11463 question->RecentAnswerPkts = 0;
11464 question->CurrentAnswers = 0;
11473 if (question->flags & kDNSServiceFlagsThresholdOne)
11474 question->BrowseThreshold = 1;
11475 else if (question->flags & kDNSServiceFlagsThresholdFinder)
11476 question->BrowseThreshold = mDNSFinderBrowseThreshold;
11478 question->BrowseThreshold = 0;
11481 question->BrowseThreshold = 0;
11483 question->CachedAnswerNeedsUpdate = mDNSfalse;
11485 question->LargeAnswers = 0;
11486 question->UniqueAnswers = 0;
11487 question->LOAddressAnswers = 0;
11488 question->FlappingInterface1 = mDNSNULL;
11489 question->FlappingInterface2 = mDNSNULL;
11492 // since we would already have the question->ServiceID in that case.
11493 if (!(question->flags & kDNSServiceFlagsServiceIndex))
11494 mDNSPlatformGetDNSRoutePolicy(m, question, &isCellBlocked);
11496 LogInfo("InitCommonState: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] is already set by client", question->qname.c,
11497 DNSTypeName(question->qtype), question->pid, question->euid, question->ServiceID);
11499 InitDNSConfig(m, question);
11501 question->AuthInfo = GetAuthInfoForQuestion(m, question);
11502 question->SuppressQuery = 0;
11503 if (question->SuppressUnusable)
11504 question->SuppressQuery = ShouldSuppressQuery(m, question);
11508 question->DisallowPID = (question->ServiceID == 0 || (isCellBlocked && question->qDNSServer && question->qDNSServer->cellIntf));
11509 if (question->DisallowPID)
11510 LogInfo("InitCommonState: Query suppressed for %##s (%s), PID %d/ServiceID %d not allowed", question->qname.c,
11511 DNSTypeName(question->qtype), question->pid, question->ServiceID);
11513 question->NextInDQList = mDNSNULL;
11514 question->SendQNow = mDNSNULL;
11515 question->SendOnAll = mDNSfalse;
11518 question->RequestUnicast = SET_QU_IN_FIRST_FOUR_QUERIES;
11520 question->RequestUnicast = SET_QU_IN_FIRST_QUERY;
11528 if (question->flags & kDNSServiceFlagsUnicastResponse)
11530 question->RequestUnicast = SET_QU_IN_FIRST_FOUR_QUERIES;
11531 LogInfo("InitCommonState: setting RequestUnicast = %d for %##s (%s)", question->RequestUnicast, question->qname.c,
11532 DNSTypeName(question->qtype));
11534 else if (question->flags & kDNSServiceFlagsThresholdFinder)
11538 question->RequestUnicast = SET_QU_IN_FIRST_FOUR_QUERIES;
11540 question->RequestUnicast = SET_QU_IN_FIRST_QUERY;
11544 question->RequestUnicast, question->qname.c, DNSTypeName(question->qtype));
11548 question->LastQTxTime = m->timenow;
11549 question->CNAMEReferrals = 0;
11551 question->WakeOnResolveCount = 0;
11552 if (question->WakeOnResolve)
11554 question->WakeOnResolveCount = InitialWakeOnResolveCount;
11559 question->DupSuppress[i].InterfaceID = mDNSNULL;
11561 question->Restart = 0;
11564 question->qname.c, DNSTypeName(question->qtype), question->InterfaceID, m->timenow,
11565 NextQSendTime(question) - m->timenow,
11566 question->DelayAnswering ? question->DelayAnswering - m->timenow : 0,
11567 question, question->DuplicateOf ? "duplicate of" : "not duplicate", question->DuplicateOf);
11569 if (question->DelayAnswering)
11571 question->DelayAnswering - m->timenow, question->qname.c, DNSTypeName(question->qtype));
11577 mDNSlocal void InitWABState(DNSQuestion *const question)
11579 // We'll create our question->LocalSocket on demand, if needed.
11583 question->LocalSocket = mDNSNULL;
11584 question->unansweredQueries = 0;
11585 question->nta = mDNSNULL;
11586 question->servAddr = zeroAddr;
11587 question->servPort = zeroIPPort;
11588 question->tcp = mDNSNULL;
11589 question->NoAnswer = NoAnswer_Normal;
11606 mDNSlocal void InitLLQState(DNSQuestion *const question)
11608 question->state = LLQ_InitialRequest;
11609 question->ReqLease = 0;
11610 question->expire = 0;
11611 question->ntries = 0;
11612 question->id = zeroOpaque64;
11617 mDNSlocal void InitDNSSECProxyState(mDNS *const m, DNSQuestion *const question)
11626 if (question->qDNSServer)
11628 if (question->qDNSServer->cellIntf)
11630 debugf("InitDNSSECProxyState: Turning off validation for %##s (%s); going over cell", question->qname.c, DNSTypeName(question->qtype));
11631 question->ValidationRequired = mDNSfalse;
11633 if (DNSSECOptionalQuestion(question) && !(question->qDNSServer->req_DO))
11636 question->qname.c, DNSTypeName(question->qtype));
11637 question->ValidationRequired = DNSSEC_VALIDATION_NONE;
11640 question->ValidationState = (question->ValidationRequired ? DNSSECValRequired : DNSSECValNotRequired);
11641 question->ValidationStatus = 0;
11642 question->responseFlags = zeroID;
11645 // Once the question is completely initialized including the duplicate logic, this function
11646 // is called to finalize the unicast question which requires flushing the cache if needed,
11648 mDNSlocal void FinalizeUnicastQuestion(mDNS *const m, DNSQuestion *question, mDNSBool purge)
11650 // Ensure DNS related info of duplicate question is same as the orig question
11651 if (question->DuplicateOf)
11654 question->validDNSServers = question->DuplicateOf->validDNSServers;
11655 question->qDNSServer = question->DuplicateOf->qDNSServer;
11656 LogInfo("FinalizeUnicastQuestion: Duplicate question %p (%p) %##s (%s), DNS Server %#a:%d",
11657 question, question->DuplicateOf, question->qname.c, DNSTypeName(question->qtype),
11658 question->qDNSServer ? &question->qDNSServer->addr : mDNSNULL,
11659 mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zp));
11662 ActivateUnicastQuery(m, question, mDNSfalse);
11665 // DNS server on the question
11668 question->DelayAnswering = 0;
11669 mDNS_PurgeForQuestion(m, question);
11671 else if (!question->DuplicateOf && DNSSECQuestion(question))
11674 CheckForDNSSECRecords(m, question);
11676 if (question->LongLived)
11679 // we determine that it is a unicast question. LongLived is set for
11690 mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const question)
11701 vStatus = ValidateParameters(m, question);
11705 question->TargetQID =
11707 (question->Target.type || Question_uDNS(question)) ? mDNS_NewMessageID(m) :
11710 debugf("mDNS_StartQuery_internal: %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
11714 if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P)
11716 while (*q && *q != question)
11721 LogMsg("mDNS_StartQuery_internal: Error! Tried to add a question %##s (%s) %p that's already in the active list",
11722 question->qname.c, DNSTypeName(question->qtype), question);
11725 *q = question;
11728 // Intialize the question. The only ordering constraint we have today is that
11733 purge = InitCommonState(m, question);
11734 InitWABState(question);
11735 InitLLQState(question);
11736 InitDNSSECProxyState(m, question);
11740 // question.
11741 question->DuplicateOf = FindDuplicateQuestion(m, question);
11742 if (question->DuplicateOf)
11743 question->AuthInfo = question->DuplicateOf->AuthInfo;
11745 if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P)
11748 m->NewLocalOnlyQuestions = question;
11753 m->NewQuestions = question;
11755 // If the question's id is non-zero, then it's Wide Area
11758 // NS, etc.) and if we haven't finished setting up our own question and setting
11760 // this routine with the question list data structures in an inconsistent state.
11761 if (!mDNSOpaque16IsZero(question->TargetQID))
11763 FinalizeUnicastQuestion(m, question, purge);
11770 m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, question->qname.c, DNSTypeName(question->qtype));
11776 LogInfo("mDNS_StartQuery_internal: Purging for %##s", question->qname.c);
11777 mDNS_PurgeForQuestion(m, question);
11788 debugf("CancelGetZoneData %##s (%s)", nta->question.qname.c, DNSTypeName(nta->question.qtype));
11789 // This function may be called anytime to free the zone information.The question may or may not have stopped.
11792 if (nta->question.ThisQInterval != -1)
11794 mDNS_StopQuery_internal(m, &nta->question);
11795 if (nta->question.ThisQInterval != -1)
11796 LogMsg("CancelGetZoneData: Question %##s (%s) ThisQInterval %d not -1", nta->question.qname.c, DNSTypeName(nta->question.qtype), nta->question.ThisQInterval);
11801 mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const question)
11803 const mDNSu32 slot = HashSlot(&question->qname);
11804 CacheGroup *cg = CacheGroupForName(m, slot, question->qnamehash, &question->qname);
11808 //LogInfo("mDNS_StopQuery_internal %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
11810 if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P) qp = &m->LocalOnlyQuestions;
11811 while (*qp && *qp != question) qp=&(*qp)->next;
11816 if (question->ThisQInterval >= 0) // Only log error message if the query was supposed to be active
11818 LogFatalError("mDNS_StopQuery_internal: Question %##s (%s) not found in active list", question->qname.c, DNSTypeName(question->qtype));
11823 if (question->InterfaceID != mDNSInterface_LocalOnly && question->InterfaceID != mDNSInterface_P2P && mDNSOpaque16IsZero(question->TargetQID))
11829 m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, question->qname.c, DNSTypeName(question->qtype));
11834 if (Question_uDNS(question) && !question->metrics.answered)
11840 metrics = &question->metrics;
11841 queryName = metrics->originalQName ? metrics->originalQName : &question->qname;
11842 isForCellular = (question->qDNSServer && question->qDNSServer->cellIntf);
11847 // Take care to cut question from list *before* calling UpdateQuestionDuplicates
11848 UpdateQuestionDuplicates(m, question);
11850 question->ThisQInterval = -1;
11852 // If there are any cache records referencing this as their active question, then see if there is any
11853 // other question that is also referencing them, else their CRActiveQuestion needs to get set to NULL.
11856 if (rr->CRActiveQuestion == question)
11865 debugf("mDNS_StopQuery_internal: Updating CRActiveQuestion to %p for cache record %s, Original question CurrentAnswers %d, new question "
11866 "CurrentAnswers %d, SuppressQuery %d", q, CRDisplayString(m,rr), question->CurrentAnswers, q->CurrentAnswers, q->SuppressQuery);
11872 // If we just deleted the question that CacheRecordAdd() or CacheRecordRmv() is about to look at,
11873 // bump its pointer forward one question.
11874 if (m->CurrentQuestion == question)
11876 debugf("mDNS_StopQuery_internal: Just deleted the currently active question: %##s (%s)",
11877 question->qname.c, DNSTypeName(question->qtype));
11878 m->CurrentQuestion = question->next;
11881 if (m->NewQuestions == question)
11883 debugf("mDNS_StopQuery_internal: Just deleted a new question that wasn't even answered yet: %##s (%s)",
11884 question->qname.c, DNSTypeName(question->qtype));
11885 m->NewQuestions = question->next;
11888 if (m->NewLocalOnlyQuestions == question) m->NewLocalOnlyQuestions = question->next;
11890 if (m->RestartQuestion == question)
11892 LogMsg("mDNS_StopQuery_internal: Just deleted the current restart question: %##s (%s)",
11893 question->qname.c, DNSTypeName(question->qtype));
11894 m->RestartQuestion = question->next;
11897 if (m->ValidationQuestion == question)
11899 LogInfo("mDNS_StopQuery_internal: Just deleted the current Validation question: %##s (%s)",
11900 question->qname.c, DNSTypeName(question->qtype));
11901 m->ValidationQuestion = question->next;
11904 // Take care not to trash question->next until *after* we've updated m->CurrentQuestion and m->NewQuestions
11905 question->next = mDNSNULL;
11907 // LogMsg("mDNS_StopQuery_internal: Question %##s (%s) removed", question->qname.c, DNSTypeName(question->qtype));
11910 // Must not do this until last, because there's a good chance the GetZoneData question is the next in the list,
11911 // so if we delete it earlier in this routine, we could find that our "question->next" pointer above is already
11914 if (question->tcp) { DisposeTCPConn(question->tcp); question->tcp = mDNSNULL; }
11915 if (question->LocalSocket) { mDNSPlatformUDPClose(question->LocalSocket); question->LocalSocket = mDNSNULL; }
11916 if (!mDNSOpaque16IsZero(question->TargetQID) && question->LongLived)
11937 if (question->state == LLQ_Established)
11939 question->ReqLease = 0;
11940 sendLLQRefresh(m, question);
11942 // We clear the tcp->question backpointer so that when the TCP connection completes, it doesn't
11943 // crash trying to access our cancelled question, but we don't cancel the TCP operation itself --
11945 if (question->tcp)
11947 question->tcp->question = mDNSNULL;
11948 question->tcp = mDNSNULL;
11956 if (question->nta) { CancelGetZoneData(m, question->nta); question->nta = mDNSNULL; }
11958 if (question->ValidationRequired && question->DNSSECAuthInfo)
11960 LogInfo("mDNS_StopQuery_internal: freeing DNSSECAuthInfo %##s", question->qname.c);
11961 question->DAIFreeCallback(m, question->DNSSECAuthInfo);
11962 question->DNSSECAuthInfo = mDNSNULL;
11964 if (question->AnonInfo)
11966 FreeAnonInfo(question->AnonInfo);
11967 question->AnonInfo = mDNSNULL;
11970 if (question->metrics.originalQName)
11972 mDNSPlatformMemFree(question->metrics.originalQName);
11973 question->metrics.originalQName = mDNSNULL;
11980 mDNSexport mStatus mDNS_StartQuery(mDNS *const m, DNSQuestion *const question)
11984 status = mDNS_StartQuery_internal(m, question);
11989 mDNSexport mStatus mDNS_StopQuery(mDNS *const m, DNSQuestion *const question)
11993 status = mDNS_StopQuery_internal(m, question);
11999 // Specifically, question callbacks invoked as a result of this call cannot themselves make API calls.
12002 mDNSexport mStatus mDNS_StopQueryWithRemoves(mDNS *const m, DNSQuestion *const question)
12008 // Check if question is new -- don't want to give remove events for a question we haven't even answered yet
12009 for (qq = m->NewQuestions; qq; qq=qq->next) if (qq == question) break;
12011 status = mDNS_StopQuery_internal(m, question);
12015 const mDNSu32 slot = HashSlot(&question->qname);
12016 CacheGroup *const cg = CacheGroupForName(m, slot, question->qnamehash, &question->qname);
12017 LogInfo("Generating terminal removes for %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
12019 if (rr->resrec.RecordType != kDNSRecordTypePacketNegative && SameNameRecordAnswersQuestion(&rr->resrec, question))
12022 if (question->QuestionCallback)
12023 question->QuestionCallback(m, question, &rr->resrec, QC_rmv);
12053 mDNSlocal mStatus mDNS_StartBrowse_internal(mDNS *const m, DNSQuestion *const question,
12059 question->InterfaceID = InterfaceID;
12060 question->flags = flags;
12061 question->Target = zeroAddr;
12062 question->qtype = kDNSType_PTR;
12063 question->qclass = kDNSClass_IN;
12064 question->LongLived = mDNStrue;
12065 question->ExpectUnique = mDNSfalse;
12066 question->ForceMCast = ForceMCast;
12067 question->ReturnIntermed = mDNSfalse;
12068 question->SuppressUnusable = mDNSfalse;
12069 question->DenyOnCellInterface = mDNSfalse;
12070 question->DenyOnExpInterface = mDNSfalse;
12071 question->SearchListIndex = 0;
12072 question->AppendSearchDomains = 0;
12073 question->RetryWithSearchDomains = mDNSfalse;
12074 question->TimeoutQuestion = 0;
12075 question->WakeOnResolve = 0;
12076 question->UseBackgroundTrafficClass = useBackgroundTrafficClass;
12077 question->ValidationRequired = 0;
12078 question->ValidatingResponse = 0;
12079 question->ProxyQuestion = 0;
12080 question->qnameOrig = mDNSNULL;
12081 question->AnonInfo = mDNSNULL;
12082 question->QuestionCallback = Callback;
12083 question->QuestionContext = Context;
12085 if (!ConstructServiceName(&question->qname, mDNSNULL, srv, domain))
12090 question->AnonInfo = AllocateAnonInfo(&question->qname, anondata, mDNSPlatformStrLen(anondata), mDNSNULL);
12091 if (!question->AnonInfo)
12095 return(mDNS_StartQuery_internal(m, question));
12098 mDNSexport mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question,
12106 status = mDNS_StartBrowse_internal(m, question, srv, domain, anondata, InterfaceID, flags, ForceMCast, useBackgroundTrafficClass, Callback, Context);
12119 mDNSlocal void FoundServiceInfoSRV(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
12121 ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
12180 mDNSlocal void FoundServiceInfoTXT(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
12182 ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
12205 mDNSlocal void FoundServiceInfo(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
12207 ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
12255 query->qSRV.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
12283 query->qTXT.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
12311 query->qAv4.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
12339 query->qAv6.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
12401 mDNSexport mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, mDNS_DomainType DomainType, const domainname *dom,
12404 question->InterfaceID = InterfaceID;
12405 question->flags = 0;
12406 question->Target = zeroAddr;
12407 question->qtype = kDNSType_PTR;
12408 question->qclass = kDNSClass_IN;
12409 question->LongLived = mDNSfalse;
12410 question->ExpectUnique = mDNSfalse;
12411 question->ForceMCast = mDNSfalse;
12412 question->ReturnIntermed = mDNSfalse;
12413 question->SuppressUnusable = mDNSfalse;
12414 question->DenyOnCellInterface = mDNSfalse;
12415 question->DenyOnExpInterface = mDNSfalse;
12416 question->SearchListIndex = 0;
12417 question->AppendSearchDomains = 0;
12418 question->RetryWithSearchDomains = mDNSfalse;
12419 question->TimeoutQuestion = 0;
12420 question->WakeOnResolve = 0;
12421 question->UseBackgroundTrafficClass = mDNSfalse;
12422 question->ValidationRequired = 0;
12423 question->ValidatingResponse = 0;
12424 question->ProxyQuestion = 0;
12425 question->qnameOrig = mDNSNULL;
12426 question->AnonInfo = mDNSNULL;
12427 question->pid = mDNSPlatformGetPID();
12428 question->euid = 0;
12429 question->QuestionCallback = Callback;
12430 question->QuestionContext = Context;
12432 if (!MakeDomainNameFromDNSNameString(&question->qname, mDNS_DomainTypeNames[DomainType])) return(mStatus_BadParamErr);
12434 if (!AppendDomainName(&question->qname, dom)) return(mStatus_BadParamErr);
12435 return(mDNS_StartQuery(m, question));
12519 // the record list and/or question list.
12785 // We initialize ThisQInterval to -1 indicating that the question has not been started
12786 // yet. If the question (browse) is started later during interface registration, it will
12788 // question has been stopped or not before initializing it to -1 because we need to
12957 { // then reactivate this question
13009 // the record list and/or question list.
13524 // which may change the record list and/or question list.
13710 // (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
14522 // For DNSSEC question, we need the DNSSEC records also. If the cache does not
14523 // have the DNSSEC records, we need to re-issue the question with EDNS0/DO bit set.
14524 // Just re-issuing the question for RRSIGs does not work in practice as the response
14525 // may not contain the RRSIGs whose typeCovered field matches the question's qtype.
14529 // RRSIGs and if we have not already issued the question with EDNS0/DO bit set, purge
14553 // Check for a positive unicast response to the question but with qtype
14556 DNSQuestion question;
14561 // Create an identical question but with qtype
14562 mDNS_SetupQuestion(&question, q->InterfaceID, &q->qname, qtype, mDNSNULL, mDNSNULL);
14563 question.qDNSServer = q->qDNSServer;
14568 SameNameRecordAnswersQuestion(&rp->resrec, &question))
14584 LogMsg("DNSServerChangeForQuestion: ERROR: Called for duplicate question %##s", q->qname.c);
14587 // of events for all of them are consistent. Duplicates for a question are always inserted
14673 // questions here. Neither question nor cache point to mcast resolvers. Questions
14699 // - A non-scoped question picks DNSServer X, creates a cache entry with X. If a new resolver gets added later that
14700 // is a better match, we pick the new DNSServer for the question and activate the unicast query. We may or may not
14705 // we don't update the cache record's DNSServer pointer to match the question's DNSSever, as they both point to
14711 // - A non-scoped question picks DNSServer X, creates a cache entry with X. If the resolver gets removed later, we will
14712 // pick a new DNSServer for the question which may or may not be NULL and set the cache record's pointer to the same
14713 // as in question's qDNSServer if the cache record is not flushed. If there is no active question, it will be set to NULL.
14717 // non-scoped question and vice versa.
14744 // If DNS Server for this question has changed, reactivate it
14745 LogInfo("uDNS_SetupDNSConfig: Updating DNS Server from %#a:%d (%##s) to %#a:%d (%##s) for question %##s (%s) (scope:%p)",
14797 debugf("uDNS_SetupDNSConfig: Not Updating DNS server question %p %##s (%s) DNS server %#a:%d %p %d",
14813 // change affected the question. That should take care of updating the cache. But
14814 // what if there is no active question at this point when the DNS server change
14816 // them, a new question after the DNS server change could pick up these stale
14822 // active question's InterfaceID/ServiceID for looking up the right DNS server.
14826 // DNS servers or no matching DNS servers for this question. In either case,
14837 // want any new questions to pick this old value. If there is no active question,
14838 // we can't possibly re-confirm, so purge in that case. If it is a DNSSEC question,
14862 // different DNS servers can give different answers to the same question.
14869 // If we don't have an active question for this cache record, neither Purge can
14874 // If there is an active question, point to its DNSServer as long as it does not point to the
14884 LogMsg("uDNS_SetupDNSConfig: ERROR!! Cache Record %s Active question %##s (%s) (scope:%p) poining to DNSServer Address %#a"
14892 LogInfo("uDNS_SetupDNSConfig: Cache Record %s, Active question %##s (%s) (scope:%p), pointing to DNSServer %#a (to be deleted),"
14893 " resetting to question's DNSServer Address %#a", CRDisplayString(m, cr), qptr->qname.c, DNSTypeName(qptr->qtype),
14900 LogInfo("uDNS_SetupDNSConfig: Cache Record %##s has no Active question, Record's DNSServer Address %#a, Server to be deleted %#a",