Lines Matching defs:question

150 		// Depending on whether this is a multicast or unicast question we want to set either:
384 LogInfo("GenerateNegativeResponse: Generating negative response for question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
388 if (m->CurrentQuestion == q) { q->ThisQInterval = 0; } // Deactivate this question
389 // Don't touch the question after this
405 // A and B, and when we stop question A, UpdateQuestionDuplicates copies the value of CNAMEReferrals
407 // the target name is still the same), and then when we stop question B, UpdateQuestionDuplicates
410 // those cases the newly re-appended question A has a different target name and therefore cannot be
411 // a duplicate of any other question ('B') which was itself a duplicate of the previous question A.
441 // Note: All the callers should use the m->CurrentQuestion to see if the question is still valid or not
479 // The callback above could have caused the question to stop. Detect that
518 // our main question list, delivering answers to mDNSInterface_Any questions as appropriate,
582 // Number of wakeups we send if WakeOnResolve is set in the question
1357 // Note: mDNS_Deregister_internal can call a user callback, which may change the record list and/or question list.
1461 // The AnswerAllLocalQuestionsWithLocalAuthRecord routine walks the question list invoking client callbacks, using the "m->CurrentQuestion"
1462 // mechanism to cope with the client callback modifying the question list while that's happening.
1516 // We may want to consider changing this code so that we generate local-only question "rmv"
1765 // which may change the record list and/or question list.
2039 // the record list and/or question list.
2517 // If we have an active question, then see if we want to schedule a refresher query for this record.
2561 // BuildQuestion puts a question into a DNS Query packet and if successful, updates the value of queryptr.
2573 debugf("BuildQuestion: No more space in this packet for question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
2589 SameNameRecordAnswersQuestion(&rr->resrec, q) && // which answers our question
2603 // If we're trying to put more than one question in this packet, and it doesn't fit
2604 // then undo that last question and try again next time
2607 debugf("BuildQuestion: Retracting question %##s (%s) new forecast total %d",
2625 SameNameRecordAnswersQuestion(&rr->resrec, q)) // which answers our question
2764 LogMsg("mDNSSendWakeOnResolve: ERROR!! Invalid InterfaceID %p for question %##s", InterfaceID, q->qname.c);
2823 SameNameRecordAnswersQuestion(&rr->resrec, q) && // which answers our question
2838 // 1. The Question Section contains the question
2916 q->SendQNow = mDNSInterfaceMark; // Mark this question for sending on all interfaces
2922 // m->CurrentQuestion point to the right question
2927 LogInfo("SendQueries question loop 1: Skipping NewQuestion %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
2937 // next thing we do is scan the list and call SetNextQueryTime() for every question we find, so we know we end up with the right value.
2950 q->SendQNow = mDNSInterfaceMark; // Mark this question for sending on all interfaces
2979 // If we recorded a duplicate suppression for this question less than half an interval ago,
3095 debugf("SendQueries: %s question for %##s (%s) at %d forecast total %d",
3099 // If we're suppressing this question, or we successfully put it, update its SendQNow state
3135 // Put our known answer list (either new one from this question or questions, or remainder of old one from last time)
3152 // If we ran out of space and we have more than one question in the packet, that's an error --
3153 // we shouldn't have put more than one question if there was a risk of us running out of space.
3194 LogMsg("SendQueries: Should not have more than one question (%d) in a truncated packet", m->omsg.h.numQuestions);
3250 for (x = m->NewQuestions; x; x=x->next) if (x == q) break; // Check if this question is a NewQuestion
3251 LogMsg("SendQueries: No active interface %p to send %s question: %p %##s (%s)", q->SendQNow, x ? "new" : "old", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
3299 // Note: AnswerCurrentQuestionWithResourceRecord can call a user callback, which may change the record list and/or question list.
3301 // In fact, to enforce this, the routine will *only* answer the question currently pointed to by m->CurrentQuestion,
3302 // which will be auto-advanced (possibly to NULL) if the client callback cancels the question.
3396 // 2) There are cache records but the DNSServers between question and cache record don't match.
3405 // changes because when we do the callback, the question can get deleted and the calling function would not
3407 // question
3429 // We are going to look through the cache for this question since it changed
3441 LogInfo("AnswerQuestionsForDNSServerChanges: Calling AnswerCurrentQuestionWithResourceRecord for question %p %##s using resource record %s",
3443 // When this question penalizes a DNS server and has no more DNS servers to pick, we normally
3444 // deliver a negative cache response and suspend the question for 60 seconds (see uDNS_CheckCurrentQuestion).
3446 // of changing DNS servers. When the cache entry is about to expire, we will resend the question and
3503 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
3507 // which may change the record list and/or question list.
3519 // If this question is one that's actively sending queries, and it's received ten answers within one
3538 verbosedebugf("CacheRecordAdd %p %##s (%s) %lu %#a:%d question %p", rr, rr->resrec.name->c,
3579 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
3581 // but we don't have any place to cache it. We'll deliver question 'add' events now, but we won't have any
3585 // which may change the record list and/or question list.
3607 // Note that CacheRecordRmv is *only* called for records that are referenced by at least one active question.
3609 // the end of the question list, and m->NewQuestions will be set to indicate the first new question.
3613 // which may change the record list and/or question list.
3627 // When a question enters suppressed state, we generate RMV events and generate a negative
3628 // response. A cache may be present that answers this question e.g., cache entry generated
3629 // before the question became suppressed. We need to skip the suppressed questions here as
3637 // When a question changes DNS server, it is marked with deliverAddEvents if we find any
3732 // before we pick a new DNS server. As the question interval is set to MaxQuestionInterval, we may
3733 // not send out a query anytime soon. Hence, we need to reset the question interval. If this is
3760 else // else trigger our question to go out now
3786 DNSQuestion *const q = m->NewQuestions; // Grab the question we're going to answer
3799 // then CheckCacheExpiration may give this question add/remove callbacks, and it's not yet ready for that.
3802 // client callbacks, which may delete their own or any other question. Our mechanism for detecting
3803 // whether our current m->NewQuestions question got deleted by one of these callbacks is to store the
3806 // advanced it), that means the question was deleted, so we no longer need to worry about answering
3808 // values we computed for slot and cg are now stale and relate to a question that no longer exists).
3813 // deleting a question, so luckily we have an easy alternative way of detecting if our question got deleted.
3816 // This should be safe, because calling the client's question callback may cause the
3817 // question list to be modified, but should not ever cause the rrcache list to be modified.
3818 // If the client's question callback deletes the question, then m->CurrentQuestion will
3824 m->CurrentQuestion = q; // Indicate which question we're answering, so we'll know if it gets deleted
3832 // Don't touch the question if it has been stopped already
3851 // If the question is mDNSInterface_LocalOnly, all records local to the machine should be used
3878 // no local records that could possibly answer this question. As we did not check the NewLocalRecords, we
3879 // need to just peek at them to see whether it will answer this question. If it would answer, pretend
3881 // when we add new /etc/hosts entries and restart the question. It is a new question and also a new record.
3898 // If we are not supposed to answer this question, generate a negative response.
3899 // Temporarily suspend the SuppressQuery so that AnswerCurrentQuestionWithResourceRecord can answer the question
3934 // Neither a local record nor a cache entry could answer this question. If this question need to be retried
3946 // Note: When a query gets suppressed or retried with search domains, we de-activate the question.
3964 // answers for this question until *after* its scheduled transmission time, in which case
3980 DNSQuestion *q = m->NewLocalOnlyQuestions; // Grab the question we're going to answer
3988 m->CurrentQuestion = q; // Indicate which question we're answering, so we'll know if it gets deleted
3993 // 1. First walk the LocalOnly records answering the LocalOnly question
4270 LogInfo("TimeoutQuestions: question %##s timed out, time %d", q->qname.c, m->timenow - q->StopTime);
4282 // depends on having m->CurrentQuestion point to the right question
4578 // 1. When a new question is created
4582 // In cases 2 and 3 we do want to cause the question to be resent immediately (ScheduleImmediately is true)
4583 mDNSlocal void ActivateUnicastQuery(mDNS *const m, DNSQuestion *const question, mDNSBool ScheduleImmediately)
4595 if (RRTypeIsAddressType(question->qtype) && PrivateQuery(question) &&
4596 !SameDomainLabel(question->qname.c, (const mDNSu8 *)"\x0c_autotunnel6")&& question->QuestionCallback != AutoTunnelCallback)
4598 question->NoAnswer = NoAnswer_Suspended;
4599 AddNewClientTunnel(m, question);
4604 if (!question->DuplicateOf)
4607 question->qname.c, DNSTypeName(question->qtype), PrivateQuery(question) ? " (Private)" : "", ScheduleImmediately ? " ScheduleImmediately" : "");
4608 question->CNAMEReferrals = 0;
4609 if (question->nta) { CancelGetZoneData(m, question->nta); question->nta = mDNSNULL; }
4610 if (question->LongLived)
4612 question->state = LLQ_InitialRequest;
4613 question->id = zeroOpaque64;
4614 question->servPort = zeroIPPort;
4615 if (question->tcp) { DisposeTCPConn(question->tcp); question->tcp = mDNSNULL; }
4617 // If the question has local answers, then we don't want answers from outside
4618 if (ScheduleImmediately && !QuestionHasLocalAnswers(m, question))
4620 question->ThisQInterval = InitialQuestionInterval;
4621 question->LastQTime = m->timenow - question->ThisQInterval;
4622 SetNextQueryTime(m, question);
4640 // we are going to stop the question. Hence we need to deliver the RMV event before we
4641 // stop the question.
4644 // application callback can potentially stop the current question (detected by CurrentQuestion) or
4645 // *any* other question which could be the next one that we may process here. RestartQuestion
4646 // points to the "next" question which will be automatically advanced in mDNS_StopQuery_internal
4647 // if the "next" question is stopped while the CurrentQuestion is stopped
4659 // question) through their "nta" pointer. Normally when the original query stops, it stops the
4660 // GetZoneData question and also frees the memory (See CancelGetZoneData). If we stop the GetZoneData
4661 // question followed by the original query that refers to this GetZoneData question, we will end up
4662 // freeing the GetZoneData question and then start the "freed" question at the end.
4668 // debug stuff, we just try to find the referencing question and don't do much with it
4671 if (q == &refq->nta->question)
4703 LogInfo("mDNSCoreRestartAddressQueries: Stop question %p %##s (%s), AppendSearchDomains %d, qnameOrig %p", q,
4731 LogInfo("mDNSCoreRestartAddressQueries: Start question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
4758 q->ThisQInterval = InitialQuestionInterval; // MUST be > zero for an active question
4984 mDNSlocal void NetWakeResolve(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
4986 NetworkInterfaceInfo *intf = (NetworkInterfaceInfo *)question->QuestionContext;
4987 int sps = (int)(question - intf->NetWakeResolve);
4992 if (answer->rrtype != question->qtype) return; // Don't care about CNAMEs
4999 mDNS_StopQuery(m, question);
5001 AssignDomainName(&question->qname, &answer->rdata->u.srv.target);
5002 question->qtype = kDNSType_AAAA;
5003 mDNS_StartQuery(m, question);
5008 mDNS_StopQuery(m, question);
5009 question->ThisQInterval = -1;
5019 mDNS_StopQuery(m, question);
5020 LogSPS("NetWakeResolve: SPS %d %##s has no IPv6 address, will try IPv4 instead", sps, question->qname.c);
5021 question->qtype = kDNSType_A;
5022 mDNS_StartQuery(m, question);
5027 mDNS_StopQuery(m, question);
5028 question->ThisQInterval = -1;
5436 for (i=0; i<query->h.numQuestions; i++) // For each question...
5439 ptr = getQuestion(query, ptr, end, InterfaceID, &q); // get the question...
5444 if (rr->NR_AnswerTo == ptr) // If we're going to generate a record answering this question
5445 { // then put the question in the question section
5448 break; // break out of the ResponseRecords loop, and go on to the next question
5594 // the record list and/or question list.
5775 for (i=0; i<query->h.numQuestions; i++) // For each question...
5781 ptr = getQuestion(query, ptr, end, InterfaceID, &pktq); // get the question...
5798 // can result in user callbacks which may change the record list and/or question list.
5830 // We only mark this question for sending if it is at least one second since the last time we multicast it
5842 // If we don't have any answers for this question, but we do own another record with the same name,
5856 // If we couldn't answer this question, someone else might be able to,
5863 // We only do the following accelerated cache expiration and duplicate question suppression processing
5899 // Check if this question is the same as any of mine.
6275 mDNSlocal DNSQuestion *ExpectingUnicastResponseForQuestion(const mDNS *const m, const mDNSIPPort port, const mDNSOpaque16 id, const DNSQuestion *const question, mDNSBool tcp)
6283 q->qtype == question->qtype &&
6284 q->qclass == question->qclass &&
6285 q->qnamehash == question->qnamehash &&
6286 SameDomainName(&q->qname, &question->qname))
6464 // the record list and/or question list.
6539 // answer questions in this packet's question section, but which aren't tagged with this packet's
6591 // to any specific question -- any code reading records from the cache needs to make that determination for itself.)
6640 // queries to get ADD/RMV events. To lookup the question, we can't use
6642 // has already matched the question using the 64 bit Id in the packet and we use that here.
6661 // on the "id" and "source port", then this response answers the question and assume the response
6675 // If we can't find a matching question, we need to see whether we have seen records earlier that matched
6676 // the question. The code below does that. So, make this record unacceptable for now
6679 debugf("mDNSCoreReceiveResponse: Can't find question for record name %##s", m->rec.r.resrec.name->c);
6792 // match the question and we already created a cache entry in the previous pass of this loop. Now when we process
6793 // the A record, it does not match the question because the record name here is the CNAME. Hence we try to
6865 // We have to reset the question interval to MaxQuestionInterval so that we don't keep
6869 // configuration changed, without flushing the cache, we reset the question interval here.
7079 // If we did not find a positive answer and we can append search domains to this question,
7597 // is suppressed. If it is not suppressed, we do try all the DNS servers for valid answers like any other question.
7598 // The main reason for this design is that cache entries point to a *single* question and that question is responsible
7599 // for keeping the cache fresh as long as it is active. Having multiple active question for a single cache entry
7602 // If IsLLQ(Q) is true, it means the question is both:
7608 mDNSlocal DNSQuestion *FindDuplicateQuestion(const mDNS *const m, const DNSQuestion *const question)
7611 // Note: A question can only be marked as a duplicate of one that occurs *earlier* in the list.
7613 // Accordingly, we break out of the loop when we get to 'question', because there's no point searching
7615 for (q = m->Questions; q && q != question; q=q->next) // Scan our list for another question
7616 if (q->InterfaceID == question->InterfaceID && // with the same InterfaceID,
7617 SameQTarget(q, question) && // and same unicast/multicast target settings
7618 q->qtype == question->qtype && // type,
7619 q->qclass == question->qclass && // class,
7620 IsLLQ(q) == IsLLQ(question) && // and long-lived status matches
7621 (!q->AuthInfo || question->AuthInfo) && // to avoid deadlock, don't make public query dup of a private one
7622 (q->SuppressQuery == question->SuppressQuery) && // Questions that are suppressed/not suppressed
7623 q->qnamehash == question->qnamehash &&
7624 SameDomainName(&q->qname, &question->qname)) // and name
7629 // This is called after a question is deleted, in case other identical questions were being suppressed as duplicates
7630 mDNSlocal void UpdateQuestionDuplicates(mDNS *const m, DNSQuestion *const question)
7635 // This is referring to some other question as duplicate. No other question can refer to this
7636 // question as a duplicate.
7637 if (question->DuplicateOf)
7639 LogInfo("UpdateQuestionDuplicates: question %p %##s (%s) duplicate of %p %##s (%s)",
7640 question, question->qname.c, DNSTypeName(question->qtype),
7641 question->DuplicateOf, question->DuplicateOf->qname.c, DNSTypeName(question->DuplicateOf->qtype));
7646 if (q->DuplicateOf == question) // To see if any questions were referencing this as their duplicate
7653 // then inherit the state from the question that's going away
7654 q->LastQTime = question->LastQTime;
7655 q->ThisQInterval = question->ThisQInterval;
7656 q->ExpectUnicastResp = question->ExpectUnicastResp;
7657 q->LastAnswerPktNum = question->LastAnswerPktNum;
7658 q->RecentAnswerPkts = question->RecentAnswerPkts;
7659 q->RequestUnicast = question->RequestUnicast;
7660 q->LastQTxTime = question->LastQTxTime;
7661 q->CNAMEReferrals = question->CNAMEReferrals;
7662 q->nta = question->nta;
7663 q->servAddr = question->servAddr;
7664 q->servPort = question->servPort;
7665 q->qDNSServer = question->qDNSServer;
7666 q->validDNSServers = question->validDNSServers;
7667 q->unansweredQueries = question->unansweredQueries;
7668 q->noServerResponse = question->noServerResponse;
7669 q->triedAllServersOnce = question->triedAllServersOnce;
7671 q->TargetQID = question->TargetQID;
7672 q->LocalSocket = question->LocalSocket;
7674 q->state = question->state;
7675 // q->tcp = question->tcp;
7676 q->ReqLease = question->ReqLease;
7677 q->expire = question->expire;
7678 q->ntries = question->ntries;
7679 q->id = question->id;
7681 question->LocalSocket = mDNSNULL;
7682 question->nta = mDNSNULL; // If we've got a GetZoneData in progress, transfer it to the newly active question
7683 // question->tcp = mDNSNULL;
7695 if (question->tcp) LogInfo("UpdateQuestionDuplicates did not transfer tcp pointer");
7697 if (question->state == LLQ_Established)
7700 question->state = 0; // Must zero question->state, or mDNS_StopQuery_internal will clean up and cancel our LLQ from the server
7807 mDNSlocal mDNSu32 GetTimeoutForMcastQuestion(mDNS *m, DNSQuestion *question)
7810 int bestmatchlen = -1, namecount = CountLabels(&question->qname);
7816 bettermatch = BetterMatchForName(&question->qname, namecount, &curr->domain, currcount, bestmatchlen);
7825 LogInfo("GetTimeoutForMcastQuestion: question %##s curmatch %p, Timeout %d", question->qname.c, curmatch,
7830 // Sets all the Valid DNS servers for a question
7831 mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
7834 int bestmatchlen = -1, namecount = CountLabels(&question->qname);
7840 question->validDNSServers = zeroOpaque64;
7860 if ((!curr->scoped && (!question->InterfaceID || (question->InterfaceID == mDNSInterface_Unicast))) || (curr->interface == question->InterfaceID))
7862 bettermatch = BetterMatchForName(&question->qname, namecount, &curr->domain, currcount, bestmatchlen);
7872 if (bettermatch) { debugf("SetValidDNSServers: Resetting all the bits"); question->validDNSServers = zeroOpaque64; timeout = 0; }
7873 debugf("SetValidDNSServers: question %##s Setting the bit for DNS server Address %#a (Domain %##s), Scoped:%d index %d,"
7874 " Timeout %d, interface %p", question->qname.c, &curr->addr, curr->domain.c, curr->scoped, index, curr->timeout,
7877 bit_set_opaque64(question->validDNSServers, index);
7882 question->noServerResponse = 0;
7884 debugf("SetValidDNSServers: ValidDNSServer bits 0x%x%x for question %p %##s (%s)",
7885 question->validDNSServers.l[1], question->validDNSServers.l[0], question, question->qname.c, DNSTypeName(question->qtype));
7919 // If there are multiple best servers for a given question, we will pick the first one
7933 // zero InterfaceID or non-zero InterfaceID on the question. Specifying an InterfaceID on
7934 // the question will cause an extra check on matching the InterfaceID on the question
7939 // only when the question has non-zero interfaceID.
7945 // This happens when we initially walk all the DNS servers and set the validity bit on the question.
7992 // Look up a DNS Server for a question within its valid DNSServer bits
7993 mDNSexport DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question)
7997 mDNSInterfaceID InterfaceID = question->InterfaceID;
7998 const domainname *name = &question->qname;
8006 if (!mDNSOpaque64IsZero(&question->validDNSServers))
8008 curmatch = GetBestServer(m, name, InterfaceID, question->validDNSServers, &currindex, mDNSfalse);
8009 if (currindex != -1) bit_clr_opaque64(question->validDNSServers, currindex);
8013 LogInfo("GetServerForQuestion: %p DNS server %#a:%d (Penalty Time Left %d) (Scope %s:%p) found for name %##s (%s)", question, &curmatch->addr,
8015 InterfaceID, name, DNSTypeName(question->qtype));
8017 LogInfo("GetServerForQuestion: %p no DNS server (Scope %s:%p) found for name %##s (%s)", question, ifname ? ifname : "None", InterfaceID, name, DNSTypeName(question->qtype));
8055 if (InterfaceID != mDNSInterface_Unicast && IsLocalDomain(qname)) { LogInfo("ShouldSuppressQuery: Query not suppressed for %##s, qtype %s, Local question", qname, DNSTypeName(qtype)); return mDNSfalse; }
8108 LogInfo("CacheRecordRmvEventsForCurrentQuestion: CacheRecord %s Suppressing RMV events for question %p %##s (%s), CRActiveQuestion %p, CurrentAnswers %d",
8115 LogInfo("CacheRecordRmvEventsForCurrentQuestion: Calling AnswerCurrentQuestionWithResourceRecord (RMV) for question %##s using resource record %s LocalAnswers %d",
8125 // If this was the active question for this cache entry, it was the one that was
8128 // when the cache entry is about to expire, we won't find an active question
8136 "Original question CurrentAnswers %d, new question CurrentAnswers %d, SuppressUnusable %d, SuppressQuery %d",
8148 mDNSlocal mDNSBool IsQuestionNew(mDNS *const m, DNSQuestion *question)
8152 if (q == question) return mDNStrue;
8197 // Returns false if the question got deleted while delivering the RMV events
8205 // If it is a new question, we have not delivered any ADD events yet. So, don't deliver RMV events.
8206 // If this question was answered using local auth records, then you can't deliver RMVs using cache
8214 else { LogInfo("CacheRecordRmvEventsForQuestion: Question %p %##s (%s) is a new question", q, q->qname.c, DNSTypeName(q->qtype)); }
8231 // application callback can potentially stop the current question (detected by CurrentQuestion) or
8232 // *any* other question which could be the next one that we may process here. RestartQuestion
8233 // points to the "next" question which will be automatically advanced in mDNS_StopQuery_internal
8234 // if the "next" question is stopped while the CurrentQuestion is stopped
8257 // AnswerCurrentQuestionWithResourceRecord can answer the question
8265 // question below, we need to deliver the RMV events so that the ADDs that will be delivered during
8271 // 1. Previously it was suppressed and now it is not suppressed, restart the question so
8272 // that it will start as a new question. Note that we can't just call ActivateUnicastQuery
8274 // this question if the cache entry did not change. Hence, we need to restart
8278 // so that we redo the duplicate checks in mDNS_StartQuery_internal. A SuppressUnusable question
8279 // is a duplicate of non-SuppressUnusable question if it is not suppressed (SuppressQuery is false).
8280 // A SuppressUnusable question is not a duplicate of non-SuppressUnusable question if it is suppressed
8281 // (SuppressQuery is true). The reason for this is that when a question is suppressed, we want an
8282 // immediate response and not want to be blocked behind a question that is querying DNS servers. When
8283 // the question is not suppressed, we don't want two active questions sending packets on the wire.
8284 // This affects both efficiency and also the current design where there is only one active question
8289 // If there are duplicate questions, calling stop inherits the values from another question on the list (which
8290 // will soon become the real question) including q->ThisQInterval which might be zero if it was
8296 LogInfo("CheckSuppressUnusableQuestions: Stop question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
8308 LogInfo("CheckSuppressUnusableQuestions: Start question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
8313 mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const question)
8315 if (question->Target.type && !ValidQuestionTarget(question))
8317 LogMsg("mDNS_StartQuery_internal: Warning! Target.type = %ld port = %u (Client forgot to initialize before calling mDNS_StartQuery? for question %##s)",
8318 question->Target.type, mDNSVal16(question->TargetPort), question->qname.c);
8319 question->Target.type = mDNSAddrType_None;
8322 if (!question->Target.type) question->TargetPort = zeroIPPort; // If no question->Target specified clear TargetPort
8324 question->TargetQID =
8326 (question->Target.type || Question_uDNS(question)) ? mDNS_NewMessageID(m) :
8330 debugf("mDNS_StartQuery: %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
8339 if (!ValidateDomainName(&question->qname))
8341 LogMsg("Attempt to start query with invalid qname %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
8347 if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P) q = &m->LocalOnlyQuestions;
8348 while (*q && *q != question) q=&(*q)->next;
8352 LogMsg("Error! Tried to add a question %##s (%s) %p that's already in the active list",
8353 question->qname.c, DNSTypeName(question->qtype), question);
8357 *q = question;
8359 // If this question is referencing a specific interface, verify it exists
8360 if (question->InterfaceID && question->InterfaceID != mDNSInterface_LocalOnly && question->InterfaceID != mDNSInterface_Unicast && question->InterfaceID != mDNSInterface_P2P)
8362 NetworkInterfaceInfo *intf = FirstInterfaceForID(m, question->InterfaceID);
8364 LogMsg("Note: InterfaceID %p for question %##s (%s) not currently found in active interface list",
8365 question->InterfaceID, question->qname.c, DNSTypeName(question->qtype));
8368 // Note: In the case where we already have the answer to this question in our cache, that may be all the client
8369 // wanted, and they may immediately cancel their question. In this case, sending an actual query on the wire would
8373 question->next = mDNSNULL;
8374 question->qnamehash = DomainNameHashValue(&question->qname); // MUST do this before FindDuplicateQuestion()
8375 question->DelayAnswering = CheckForSoonToExpireRecords(m, &question->qname, question->qnamehash, HashSlot(&question->qname));
8376 question->LastQTime = m->timenow;
8377 question->ThisQInterval = InitialQuestionInterval; // MUST be > zero for an active question
8378 question->ExpectUnicastResp = 0;
8379 question->LastAnswerPktNum = m->PktNum;
8380 question->RecentAnswerPkts = 0;
8381 question->CurrentAnswers = 0;
8382 question->LargeAnswers = 0;
8383 question->UniqueAnswers = 0;
8384 question->LOAddressAnswers = 0;
8385 question->FlappingInterface1 = mDNSNULL;
8386 question->FlappingInterface2 = mDNSNULL;
8388 question->AuthInfo = GetAuthInfoForQuestion(m, question);
8389 if (question->SuppressUnusable)
8390 question->SuppressQuery = ShouldSuppressQuery(m, &question->qname, question->qtype, question->InterfaceID);
8392 question->SuppressQuery = 0;
8393 question->DuplicateOf = FindDuplicateQuestion(m, question);
8394 question->NextInDQList = mDNSNULL;
8395 question->SendQNow = mDNSNULL;
8396 question->SendOnAll = mDNSfalse;
8397 question->RequestUnicast = 0;
8398 question->LastQTxTime = m->timenow;
8399 question->CNAMEReferrals = 0;
8401 // We'll create our question->LocalSocket on demand, if needed.
8405 question->LocalSocket = mDNSNULL;
8406 question->deliverAddEvents = mDNSfalse;
8407 question->qDNSServer = mDNSNULL;
8408 question->unansweredQueries = 0;
8409 question->nta = mDNSNULL;
8410 question->servAddr = zeroAddr;
8411 question->servPort = zeroIPPort;
8412 question->tcp = mDNSNULL;
8413 question->NoAnswer = NoAnswer_Normal;
8415 question->state = LLQ_InitialRequest;
8416 question->ReqLease = 0;
8417 question->expire = 0;
8418 question->ntries = 0;
8419 question->id = zeroOpaque64;
8420 question->validDNSServers = zeroOpaque64;
8421 question->triedAllServersOnce = 0;
8422 question->noServerResponse = 0;
8423 question->StopTime = 0;
8424 if (question->WakeOnResolve)
8426 question->WakeOnResolveCount = InitialWakeOnResolveCount;
8427 mDNS_PurgeBeforeResolve(m, question);
8430 question->WakeOnResolveCount = 0;
8432 if (question->DuplicateOf) question->AuthInfo = question->DuplicateOf->AuthInfo;
8435 question->DupSuppress[i].InterfaceID = mDNSNULL;
8438 question->qname.c, DNSTypeName(question->qtype), question->InterfaceID, m->timenow,
8439 NextQSendTime(question) - m->timenow,
8440 question->DelayAnswering ? question->DelayAnswering - m->timenow : 0,
8441 question, question->DuplicateOf ? "duplicate of" : "not duplicate", question->DuplicateOf);
8443 if (question->DelayAnswering)
8445 question->DelayAnswering - m->timenow, question->qname.c, DNSTypeName(question->qtype));
8447 if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P)
8449 if (!m->NewLocalOnlyQuestions) m->NewLocalOnlyQuestions = question;
8453 if (!m->NewQuestions) m->NewQuestions = question;
8455 // If the question's id is non-zero, then it's Wide Area
8458 // NS, etc.) and if we haven't finished setting up our own question and setting
8460 // this routine with the question list data structures in an inconsistent state.
8461 if (!mDNSOpaque16IsZero(question->TargetQID))
8465 // for the duplicate question may get a different DNS server from the original question
8466 mDNSu32 timeout = SetValidDNSServers(m, question);
8472 if (question->TimeoutQuestion)
8473 question->StopTime = NonZeroTime(m->timenow + timeout * mDNSPlatformOneSecond);
8474 if (question->DuplicateOf)
8476 question->validDNSServers = question->DuplicateOf->validDNSServers;
8477 question->qDNSServer = question->DuplicateOf->qDNSServer;
8478 LogInfo("mDNS_StartQuery_internal: Duplicate question %p (%p) %##s (%s), Timeout %d, DNS Server %#a:%d",
8479 question, question->DuplicateOf, question->qname.c, DNSTypeName(question->qtype), timeout,
8480 question->qDNSServer ? &question->qDNSServer->addr : mDNSNULL,
8481 mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zeroIPPort));
8485 question->qDNSServer = GetServerForQuestion(m, question);
8486 LogInfo("mDNS_StartQuery_internal: question %p %##s (%s) Timeout %d, DNS Server %#a:%d",
8487 question, question->qname.c, DNSTypeName(question->qtype), timeout,
8488 question->qDNSServer ? &question->qDNSServer->addr : mDNSNULL,
8489 mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zeroIPPort));
8491 ActivateUnicastQuery(m, question, mDNSfalse);
8494 if (question->LongLived && !m->LLQNAT.clientContext)
8505 if (question->LongLived)
8512 if (question->TimeoutQuestion)
8513 question->StopTime = NonZeroTime(m->timenow + GetTimeoutForMcastQuestion(m, question) * mDNSPlatformOneSecond);
8515 if (question->StopTime) SetNextQueryStopTime(m, question);
8516 SetNextQueryTime(m,question);
8526 debugf("CancelGetZoneData %##s (%s)", nta->question.qname.c, DNSTypeName(nta->question.qtype));
8527 // This function may be called anytime to free the zone information.The question may or may not have stopped.
8530 if (nta->question.ThisQInterval != -1)
8532 mDNS_StopQuery_internal(m, &nta->question);
8533 if (nta->question.ThisQInterval != -1)
8534 LogMsg("CancelGetZoneData: Question %##s (%s) ThisQInterval %d not -1", nta->question.qname.c, DNSTypeName(nta->question.qtype), nta->question.ThisQInterval);
8539 mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const question)
8541 const mDNSu32 slot = HashSlot(&question->qname);
8542 CacheGroup *cg = CacheGroupForName(m, slot, question->qnamehash, &question->qname);
8546 //LogInfo("mDNS_StopQuery_internal %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
8548 if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P) qp = &m->LocalOnlyQuestions;
8549 while (*qp && *qp != question) qp=&(*qp)->next;
8554 if (question->ThisQInterval >= 0) // Only log error message if the query was supposed to be active
8557 question->qname.c, DNSTypeName(question->qtype));
8564 // Take care to cut question from list *before* calling UpdateQuestionDuplicates
8565 UpdateQuestionDuplicates(m, question);
8567 question->ThisQInterval = -1;
8569 // If there are any cache records referencing this as their active question, then see if there is any
8570 // other question that is also referencing them, else their CRActiveQuestion needs to get set to NULL.
8573 if (rr->CRActiveQuestion == question)
8582 debugf("mDNS_StopQuery_internal: Updating CRActiveQuestion to %p for cache record %s, Original question CurrentAnswers %d, new question "
8583 "CurrentAnswers %d, SuppressQuery %d", q, CRDisplayString(m,rr), question->CurrentAnswers, q->CurrentAnswers, q->SuppressQuery);
8589 // If we just deleted the question that CacheRecordAdd() or CacheRecordRmv() is about to look at,
8590 // bump its pointer forward one question.
8591 if (m->CurrentQuestion == question)
8593 debugf("mDNS_StopQuery_internal: Just deleted the currently active question: %##s (%s)",
8594 question->qname.c, DNSTypeName(question->qtype));
8595 m->CurrentQuestion = question->next;
8598 if (m->NewQuestions == question)
8600 debugf("mDNS_StopQuery_internal: Just deleted a new question that wasn't even answered yet: %##s (%s)",
8601 question->qname.c, DNSTypeName(question->qtype));
8602 m->NewQuestions = question->next;
8605 if (m->NewLocalOnlyQuestions == question) m->NewLocalOnlyQuestions = question->next;
8607 if (m->RestartQuestion == question)
8609 LogMsg("mDNS_StopQuery_internal: Just deleted the current restart question: %##s (%s)",
8610 question->qname.c, DNSTypeName(question->qtype));
8611 m->RestartQuestion = question->next;
8614 // Take care not to trash question->next until *after* we've updated m->CurrentQuestion and m->NewQuestions
8615 question->next = mDNSNULL;
8617 // LogMsg("mDNS_StopQuery_internal: Question %##s (%s) removed", question->qname.c, DNSTypeName(question->qtype));
8620 // Must not do this until last, because there's a good chance the GetZoneData question is the next in the list,
8621 // so if we delete it earlier in this routine, we could find that our "question->next" pointer above is already
8624 if (question->tcp) { DisposeTCPConn(question->tcp); question->tcp = mDNSNULL; }
8625 if (question->LocalSocket) { mDNSPlatformUDPClose(question->LocalSocket); question->LocalSocket = mDNSNULL; }
8626 if (!mDNSOpaque16IsZero(question->TargetQID) && question->LongLived)
8645 if (question->state == LLQ_Established)
8647 question->ReqLease = 0;
8648 sendLLQRefresh(m, question);
8650 // We clear the tcp->question backpointer so that when the TCP connection completes, it doesn't
8651 // crash trying to access our cancelled question, but we don't cancel the TCP operation itself --
8653 if (question->tcp)
8655 question->tcp->question = mDNSNULL;
8656 question->tcp = mDNSNULL;
8664 if (question->nta) { CancelGetZoneData(m, question->nta); question->nta = mDNSNULL; }
8669 mDNSexport mStatus mDNS_StartQuery(mDNS *const m, DNSQuestion *const question)
8673 status = mDNS_StartQuery_internal(m, question);
8678 mDNSexport mStatus mDNS_StopQuery(mDNS *const m, DNSQuestion *const question)
8682 status = mDNS_StopQuery_internal(m, question);
8688 // Specifically, question callbacks invoked as a result of this call cannot themselves make API calls.
8691 mDNSexport mStatus mDNS_StopQueryWithRemoves(mDNS *const m, DNSQuestion *const question)
8697 // Check if question is new -- don't want to give remove events for a question we haven't even answered yet
8698 for (qq = m->NewQuestions; qq; qq=qq->next) if (qq == question) break;
8700 status = mDNS_StopQuery_internal(m, question);
8704 const mDNSu32 slot = HashSlot(&question->qname);
8705 CacheGroup *const cg = CacheGroupForName(m, slot, question->qnamehash, &question->qname);
8706 LogInfo("Generating terminal removes for %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
8708 if (rr->resrec.RecordType != kDNSRecordTypePacketNegative && SameNameRecordAnswersQuestion(&rr->resrec, question))
8711 if (question->QuestionCallback)
8712 question->QuestionCallback(m, question, &rr->resrec, mDNSfalse);
8742 mDNSlocal mStatus mDNS_StartBrowse_internal(mDNS *const m, DNSQuestion *const question,
8746 question->InterfaceID = InterfaceID;
8747 question->Target = zeroAddr;
8748 question->qtype = kDNSType_PTR;
8749 question->qclass = kDNSClass_IN;
8750 question->LongLived = mDNStrue;
8751 question->ExpectUnique = mDNSfalse;
8752 question->ForceMCast = ForceMCast;
8753 question->ReturnIntermed = mDNSfalse;
8754 question->SuppressUnusable = mDNSfalse;
8755 question->SearchListIndex = 0;
8756 question->AppendSearchDomains = 0;
8757 question->RetryWithSearchDomains = mDNSfalse;
8758 question->TimeoutQuestion = 0;
8759 question->WakeOnResolve = 0;
8760 question->qnameOrig = mDNSNULL;
8761 question->QuestionCallback = Callback;
8762 question->QuestionContext = Context;
8763 if (!ConstructServiceName(&question->qname, mDNSNULL, srv, domain)) return(mStatus_BadParamErr);
8765 return(mDNS_StartQuery_internal(m, question));
8768 mDNSexport mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question,
8774 status = mDNS_StartBrowse_internal(m, question, srv, domain, InterfaceID, ForceMCast, Callback, Context);
8787 mDNSlocal void FoundServiceInfoSRV(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
8789 ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
8848 mDNSlocal void FoundServiceInfoTXT(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
8850 ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
8873 mDNSlocal void FoundServiceInfo(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
8875 ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
8923 query->qSRV.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
8943 query->qTXT.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
8963 query->qAv4.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
8983 query->qAv6.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
9038 mDNSexport mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, mDNS_DomainType DomainType, const domainname *dom,
9041 question->InterfaceID = InterfaceID;
9042 question->Target = zeroAddr;
9043 question->qtype = kDNSType_PTR;
9044 question->qclass = kDNSClass_IN;
9045 question->LongLived = mDNSfalse;
9046 question->ExpectUnique = mDNSfalse;
9047 question->ForceMCast = mDNSfalse;
9048 question->ReturnIntermed = mDNSfalse;
9049 question->SuppressUnusable = mDNSfalse;
9050 question->SearchListIndex = 0;
9051 question->AppendSearchDomains = 0;
9052 question->RetryWithSearchDomains = mDNSfalse;
9053 question->TimeoutQuestion = 0;
9054 question->WakeOnResolve = 0;
9055 question->qnameOrig = mDNSNULL;
9056 question->QuestionCallback = Callback;
9057 question->QuestionContext = Context;
9059 if (!MakeDomainNameFromDNSNameString(&question->qname, mDNS_DomainTypeNames[DomainType])) return(mStatus_BadParamErr);
9061 if (!AppendDomainName(&question->qname, dom)) return(mStatus_BadParamErr);
9062 return(mDNS_StartQuery(m, question));
9146 // the record list and/or question list.
9524 { // then reactivate this question
9566 // the record list and/or question list.
10011 // which may change the record list and/or question list.
10203 // (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
10873 // This function is called when the DNSServer is updated to the new question. There may already be
10895 // AnswerNewQuestion if it is a new question. So, we check to see if it is a new question
10898 // question picks a DNS server for which AnswerNewQuestion could not deliver an answer even
10900 // pick a new DNSServer, those cache entries may answer this question.
10907 // got a response and the cache is expired now and we are reissuing the question but the
10944 // "q" is not a duplicate question. If it is a newQuestion, then the CRActiveQuestion can't be
10945 // possibly set as it is set only when we deliver the ADD event to the question.
10948 LogMsg("CacheRecordResetDNSServer: ERROR!!: CRActiveQuestion %p set, current question %p, name %##s", rp->CRActiveQuestion, q, q->qname.c);
10951 // if this is a new question, then we never delivered an ADD yet, so don't deliver the RMV.
10970 LogInfo("CacheRecordResetDNSServer: deliverAddEvents not set for question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
10972 LogInfo("CacheRecordResetDNSServer: deliverAddEvents not set for suppressed question %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
11002 // question. "DNSServer" here is the DNSServer object and not the DNS server itself. It is possible to
11004 // DNSServer object. By maintaining the question and the cache entries point to the same DNSServer
11007 // CacheRecordResetDNSServer should be called only once for the non-duplicate question as once the cache
11008 // entries are moved to point to the new DNSServer, we don't need to call it for the duplicate question
11009 // and it is wrong to call for the duplicate question as it's decision to mark deliverAddevents will be
11013 LogMsg("DNSServerChangeForQuestion: ERROR: Called for duplicate question %##s", q->qname.c);
11018 // of events for all of them are consistent. Duplicates for a question are always inserted
11066 // questions here. Neither question nor cache point to mcast resolvers. Questions
11095 // The new DNSServer may be a scoped or non-scoped one. We use the active question's
11129 // If DNS Server for this question has changed, reactivate it
11141 // server here to match the question and the cache record.
11144 // events for the questions, the DNSServer on the question should match the Cache Record
11168 debugf("uDNS_SetupDNSConfig: Not Updating DNS server question %p %##s (%s) DNS server %#a:%d %p %d",
11181 // different DNS servers can give different answers to the same question.
11188 // If we don't have an active question for this cache record, neither Purge can
11193 // If there is an active question, point to its DNSServer as long as it does not point to the
11196 // this question. Hence, whenever we hit a resource record with a DNSServer that is just
11197 // about to be deleted, we should never have an active question. The code below just tries to
11204 LogMsg("uDNS_SetupDNSConfig: Cache Record %s match: Active question %##s (%s) with DNSServer Address NULL, Server to be deleted %#a",
11207 LogMsg("uDNS_SetupDNSConfig: Cache Record %s match: Active question %##s (%s) DNSServer Address %#a, Server to be deleted %#a",
11223 LogInfo("uDNS_SetupDNSConfig: Cache Record %##s has no Active question, Record's DNSServer Address %#a, Server to be deleted %#a",