query.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <util/buffer.h>
  15. #include <dns/name.h>
  16. #include <dns/rrset.h>
  17. #include <dns/message.h>
  18. #include <cc/data.h>
  19. #include <datasrc/query.h>
  20. using namespace isc::dns;
  21. namespace isc {
  22. namespace datasrc {
  23. QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
  24. const isc::dns::RRType& t,
  25. const isc::dns::Message::Section sect) :
  26. q(qry), qname(n), qclass(qry.qclass()), qtype(t), section(sect),
  27. op(AUTH_QUERY), state(GETANSWER), flags(0)
  28. {}
  29. QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
  30. const isc::dns::RRType& t,
  31. const isc::dns::Message::Section sect,
  32. const Op o) :
  33. q(qry), qname(n), qclass(qry.qclass()), qtype(t), section(sect), op(o),
  34. state(GETANSWER), flags(0)
  35. {}
  36. QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
  37. const isc::dns::RRType& t,
  38. const isc::dns::Message::Section sect,
  39. const State st) :
  40. q(qry), qname(n), qclass(qry.qclass()), qtype(t), section(sect),
  41. op(AUTH_QUERY), state(st), flags(0)
  42. {}
  43. QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
  44. const isc::dns::RRType& t,
  45. const isc::dns::Message::Section sect,
  46. const Op o, const State st) :
  47. q(qry), qname(n), qclass(qry.qclass()), qtype(t), section(sect), op(o),
  48. state(st), flags(0)
  49. {}
  50. QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
  51. const isc::dns::RRType& t, const Op o) :
  52. q(qry), qname(n), qclass(qry.qclass()), qtype(t),
  53. section(Message::SECTION_ANSWER), op(o), state(GETANSWER), flags(0)
  54. {
  55. if (op != SIMPLE_QUERY) {
  56. isc_throw(Unexpected, "invalid constructor for this task operation");
  57. }
  58. }
  59. // A referral query doesn't need to specify section, state, or type.
  60. QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n, const Op o) :
  61. q(qry), qname(n), qclass(qry.qclass()), qtype(RRType::ANY()),
  62. section(Message::SECTION_ANSWER), op(o), state(GETANSWER), flags(0)
  63. {
  64. if (op != REF_QUERY) {
  65. isc_throw(Unexpected, "invalid constructor for this task operation");
  66. }
  67. }
  68. QueryTask::QueryTask(const Query& qry, const isc::dns::Name& n,
  69. const isc::dns::Message::Section sect, const Op o,
  70. const State st) :
  71. q(qry), qname(n), qclass(qry.qclass()), qtype(RRType::ANY()),
  72. section(sect), op(o), state(st), flags(0)
  73. {
  74. if (op != GLUE_QUERY && op != NOGLUE_QUERY) {
  75. isc_throw(Unexpected, "invalid constructor for this task operation");
  76. }
  77. }
  78. QueryTask::~QueryTask() {}
  79. Query::Query(Message& m, HotCache& c, bool dnssec) :
  80. status_(PENDING), qname_(NULL), qclass_(NULL), qtype_(NULL),
  81. cache_(&c), message_(&m), want_additional_(true), want_dnssec_(dnssec)
  82. {
  83. // Check message formatting
  84. if (message_->getRRCount(Message::SECTION_QUESTION) != 1) {
  85. isc_throw(Unexpected, "malformed message: too many questions");
  86. }
  87. // Populate the query task queue with the initial question
  88. QuestionPtr question = *message_->beginQuestion();
  89. qname_ = &question->getName();
  90. qclass_ = &question->getClass();
  91. qtype_ = &question->getType();
  92. restarts_ = 0;
  93. querytasks_.push(QueryTaskPtr(new QueryTask(*this, *qname_, *qtype_,
  94. Message::SECTION_ANSWER)));
  95. }
  96. Query::~Query() {}
  97. }
  98. }