message.cc 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. // Copyright (C) 2009 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. // $Id$
  15. #include <stdint.h>
  16. #include <algorithm>
  17. #include <string>
  18. #include <sstream>
  19. #include <vector>
  20. #include <boost/lexical_cast.hpp>
  21. #include <boost/shared_ptr.hpp>
  22. #include <exceptions/exceptions.h>
  23. #include "buffer.h"
  24. #include "message.h"
  25. #include "messagerenderer.h"
  26. #include "name.h"
  27. #include "question.h"
  28. #include "rdataclass.h"
  29. #include "rrclass.h"
  30. #include "rrtype.h"
  31. #include "rrttl.h"
  32. #include "rrset.h"
  33. using namespace std;
  34. using namespace boost;
  35. using namespace isc::dns;
  36. using namespace isc::dns::rdata;
  37. namespace isc {
  38. namespace dns {
  39. namespace {
  40. typedef uint16_t flags_t;
  41. // protocol constants
  42. static const size_t HEADERLEN = 12;
  43. static const flags_t FLAG_QR = 0x8000;
  44. static const flags_t FLAG_AA = 0x0400;
  45. static const flags_t FLAG_TC = 0x0200;
  46. static const flags_t FLAG_RD = 0x0100;
  47. static const flags_t FLAG_RA = 0x0080;
  48. static const flags_t FLAG_AD = 0x0020;
  49. static const flags_t FLAG_CD = 0x0010;
  50. //
  51. // EDNS related constants
  52. //
  53. static const flags_t EXTFLAG_MASK = 0xffff;
  54. static const flags_t EXTFLAG_DO = 0x8000;
  55. static const uint32_t EXTRCODE_MASK = 0xff000000;
  56. static const uint32_t EDNSVERSION_MASK = 0x00ff0000;
  57. static const unsigned int OPCODE_MASK = 0x7800;
  58. static const unsigned int OPCODE_SHIFT = 11;
  59. static const unsigned int RCODE_MASK = 0x000f;
  60. static const unsigned int FLAG_MASK = 0x8ff0;
  61. static const unsigned int MESSAGE_REPLYPRESERVE = (FLAG_RD | FLAG_CD);
  62. static const Rcode rcodes[] = {
  63. Rcode::NOERROR(),
  64. Rcode::FORMERR(),
  65. Rcode::SERVFAIL(),
  66. Rcode::NXDOMAIN(),
  67. Rcode::NOTIMP(),
  68. Rcode::REFUSED(),
  69. Rcode::YXDOMAIN(),
  70. Rcode::YXRRSET(),
  71. Rcode::NXRRSET(),
  72. Rcode::NOTAUTH(),
  73. Rcode::NOTZONE(),
  74. Rcode::RESERVED11(),
  75. Rcode::RESERVED12(),
  76. Rcode::RESERVED13(),
  77. Rcode::RESERVED14(),
  78. Rcode::RESERVED15(),
  79. Rcode::BADVERS()
  80. };
  81. static const char *rcodetext[] = {
  82. "NOERROR",
  83. "FORMERR",
  84. "SERVFAIL",
  85. "NXDOMAIN",
  86. "NOTIMP",
  87. "REFUSED",
  88. "YXDOMAIN",
  89. "YXRRSET",
  90. "NXRRSET",
  91. "NOTAUTH",
  92. "NOTZONE",
  93. "RESERVED11",
  94. "RESERVED12",
  95. "RESERVED13",
  96. "RESERVED14",
  97. "RESERVED15",
  98. "BADVERS"
  99. };
  100. static const Opcode* opcodes[] = {
  101. &Opcode::QUERY(),
  102. &Opcode::IQUERY(),
  103. &Opcode::STATUS(),
  104. &Opcode::RESERVED3(),
  105. &Opcode::NOTIFY(),
  106. &Opcode::UPDATE(),
  107. &Opcode::RESERVED6(),
  108. &Opcode::RESERVED7(),
  109. &Opcode::RESERVED8(),
  110. &Opcode::RESERVED9(),
  111. &Opcode::RESERVED10(),
  112. &Opcode::RESERVED11(),
  113. &Opcode::RESERVED12(),
  114. &Opcode::RESERVED13(),
  115. &Opcode::RESERVED14(),
  116. &Opcode::RESERVED15()
  117. };
  118. static const char *opcodetext[] = {
  119. "QUERY",
  120. "IQUERY",
  121. "STATUS",
  122. "RESERVED3",
  123. "NOTIFY",
  124. "UPDATE",
  125. "RESERVED6",
  126. "RESERVED7",
  127. "RESERVED8",
  128. "RESERVED9",
  129. "RESERVED10",
  130. "RESERVED11",
  131. "RESERVED12",
  132. "RESERVED13",
  133. "RESERVED14",
  134. "RESERVED15"
  135. };
  136. }
  137. string
  138. Opcode::toText() const
  139. {
  140. return (opcodetext[code_]);
  141. }
  142. Rcode::Rcode(uint16_t code) : code_(code)
  143. {
  144. if (code_ > MAX_RCODE) {
  145. isc_throw(OutOfRange, "Rcode is too large to construct");
  146. }
  147. }
  148. string
  149. Rcode::toText() const
  150. {
  151. if (code_ < sizeof(rcodetext) / sizeof (const char *)) {
  152. return (rcodetext[code_]);
  153. }
  154. ostringstream oss;
  155. oss << code_;
  156. return (oss.str());
  157. }
  158. namespace {
  159. inline unsigned int
  160. sectionCodeToId(const Section& section)
  161. {
  162. unsigned int code = section.getCode();
  163. assert(code > 0);
  164. return (section.getCode() - 1);
  165. }
  166. }
  167. class MessageImpl {
  168. public:
  169. MessageImpl(Message::Mode mode);
  170. // Open issues: should we rather have a header in wire-format
  171. // for efficiency?
  172. Message::Mode mode_;
  173. qid_t qid_;
  174. Rcode rcode_;
  175. const Opcode* opcode_;
  176. flags_t flags_;
  177. bool dnssec_ok_;
  178. static const unsigned int SECTION_MAX = 4; // TODO: revisit this design
  179. int counts_[SECTION_MAX]; // TODO: revisit this definition
  180. vector<QuestionPtr> questions_;
  181. vector<RRsetPtr> rrsets_[SECTION_MAX];
  182. RRsetPtr remote_edns_;
  183. uint16_t remote_udpsize_;
  184. RRsetPtr local_edns_;
  185. uint16_t udpsize_;
  186. #ifdef notyet
  187. // tsig/sig0: TODO
  188. RRsetsSorter* sorter_;
  189. #endif
  190. void init();
  191. int parseQuestion(Message& message, InputBuffer& buffer);
  192. int parseSection(Message& messge, const Section& section,
  193. InputBuffer& buffer);
  194. };
  195. MessageImpl::MessageImpl(Message::Mode mode) :
  196. mode_(mode), rcode_(Rcode::NOERROR())
  197. {
  198. init();
  199. }
  200. void
  201. MessageImpl::init()
  202. {
  203. flags_ = 0;
  204. qid_ = 0;
  205. rcode_ = Rcode::NOERROR(); // XXX
  206. opcode_ = NULL;
  207. dnssec_ok_ = false;
  208. remote_edns_ = RRsetPtr();
  209. remote_udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
  210. local_edns_ = RRsetPtr();
  211. udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
  212. for (int i = 0; i < SECTION_MAX; i++) {
  213. counts_[i] = 0;
  214. }
  215. questions_.clear();
  216. rrsets_[sectionCodeToId(Section::ANSWER())].clear();
  217. rrsets_[sectionCodeToId(Section::AUTHORITY())].clear();
  218. rrsets_[sectionCodeToId(Section::ADDITIONAL())].clear();
  219. }
  220. Message::Message(Mode mode) :
  221. impl_(new MessageImpl(mode))
  222. {
  223. }
  224. Message::~Message()
  225. {
  226. delete impl_;
  227. }
  228. bool
  229. Message::getHeaderFlag(const MessageFlag& flag) const
  230. {
  231. return ((impl_->flags_ & flag.getBit()) != 0);
  232. }
  233. void
  234. Message::setHeaderFlag(const MessageFlag& flag)
  235. {
  236. impl_->flags_ |= flag.getBit();
  237. }
  238. void
  239. Message::clearHeaderFlag(const MessageFlag& flag)
  240. {
  241. impl_->flags_ &= ~flag.getBit();
  242. }
  243. bool
  244. Message::isDNSSECSupported() const
  245. {
  246. return (impl_->dnssec_ok_);
  247. }
  248. void
  249. Message::setDNSSECSupported(bool on)
  250. {
  251. if (impl_->mode_ != Message::RENDER) {
  252. isc_throw(InvalidMessageOperation,
  253. "setDNSSECSupported performed in non-render mode");
  254. }
  255. impl_->dnssec_ok_ = on;
  256. }
  257. uint16_t
  258. Message::getUDPSize() const
  259. {
  260. return (impl_->udpsize_);
  261. }
  262. void
  263. Message::setUDPSize(uint16_t size)
  264. {
  265. if (impl_->mode_ != Message::RENDER) {
  266. isc_throw(InvalidMessageOperation,
  267. "setUDPSize performed in non-render mode");
  268. }
  269. if (size < DEFAULT_MAX_UDPSIZE) {
  270. isc_throw(InvalidMessageUDPSize,
  271. "Specified UDP message size is too small");
  272. }
  273. impl_->udpsize_ = size;
  274. }
  275. qid_t
  276. Message::getQid() const
  277. {
  278. return (impl_->qid_);
  279. }
  280. void
  281. Message::setQid(qid_t qid)
  282. {
  283. impl_->qid_ = qid;
  284. }
  285. const Rcode&
  286. Message::getRcode() const
  287. {
  288. return (impl_->rcode_);
  289. }
  290. void
  291. Message::setRcode(const Rcode& rcode)
  292. {
  293. impl_->rcode_ = rcode;
  294. }
  295. const Opcode&
  296. Message::getOpcode() const
  297. {
  298. return (*impl_->opcode_);
  299. }
  300. void
  301. Message::setOpcode(const Opcode& opcode)
  302. {
  303. impl_->opcode_ = &opcode;
  304. }
  305. unsigned int
  306. Message::getRRCount(const Section& section) const
  307. {
  308. return (impl_->counts_[section.getCode()]);
  309. }
  310. void
  311. Message::addRRset(const Section& section, RRsetPtr rrset, bool sign)
  312. {
  313. // Note: should check duplicate (TBD)
  314. impl_->rrsets_[sectionCodeToId(section)].push_back(rrset);
  315. impl_->counts_[section.getCode()] += rrset->getRdataCount();
  316. RRsetPtr sp = rrset->getRRsig();
  317. if (sign && sp) {
  318. impl_->rrsets_[sectionCodeToId(section)].push_back(sp);
  319. impl_->counts_[section.getCode()] += sp->getRdataCount();
  320. }
  321. }
  322. void
  323. Message::addQuestion(const QuestionPtr question)
  324. {
  325. impl_->questions_.push_back(question);
  326. impl_->counts_[Section::QUESTION().getCode()]++;
  327. }
  328. void
  329. Message::addQuestion(const Question& question)
  330. {
  331. addQuestion(QuestionPtr(new Question(question)));
  332. }
  333. namespace {
  334. template <typename T>
  335. struct RenderSection
  336. {
  337. RenderSection(MessageRenderer& renderer, const bool partial_ok) :
  338. counter_(0), renderer_(renderer), partial_ok_(partial_ok),
  339. truncated_(false)
  340. {}
  341. void operator()(const T& entry)
  342. {
  343. // If it's already truncated, ignore the rest of the section.
  344. if (truncated_) {
  345. return;
  346. }
  347. size_t pos0 = renderer_.getLength();
  348. counter_ += entry->toWire(renderer_);
  349. if (renderer_.isTruncated()) {
  350. truncated_ = true;
  351. if (!partial_ok_) {
  352. // roll back to the end of the previous RRset.
  353. renderer_.trim(renderer_.getLength() - pos0);
  354. }
  355. }
  356. }
  357. unsigned int getTotalCount() { return (counter_); }
  358. unsigned int counter_;
  359. MessageRenderer& renderer_;
  360. const bool partial_ok_;
  361. bool truncated_;
  362. };
  363. }
  364. namespace {
  365. bool
  366. addEDNS(MessageImpl* mimpl, MessageRenderer& renderer)
  367. {
  368. bool is_query = ((mimpl->flags_ & MessageFlag::QR().getBit()) == 0);
  369. // If this is a reply and the request didn't have EDNS, we shouldn't add it.
  370. if (mimpl->remote_edns_ == NULL && !is_query) {
  371. return (false);
  372. }
  373. // For queries, we add EDNS only when necessary:
  374. // Local UDP size is not the default value, or
  375. // DNSSEC DO bit is to be set, or
  376. // Extended Rcode is to be specified.
  377. if (is_query && mimpl->udpsize_ == Message::DEFAULT_MAX_UDPSIZE &&
  378. !mimpl->dnssec_ok_ &&
  379. mimpl->rcode_.getCode() < 0x10) {
  380. return (false);
  381. }
  382. // If adding the OPT RR would exceed the size limit, don't do it.
  383. // 11 = len(".") + type(2byte) + class(2byte) + TTL(4byte) + RDLEN(2byte)
  384. // (RDATA is empty in this simple implementation)
  385. if (renderer.getLength() + 11 > renderer.getLengthLimit()) {
  386. return (false);
  387. }
  388. // Render EDNS OPT RR
  389. uint32_t extrcode_flags = ((mimpl->rcode_.getCode() & 0xff0) << 24);
  390. if (mimpl->dnssec_ok_) {
  391. extrcode_flags |= 0x8000; // set DO bit
  392. }
  393. mimpl->local_edns_ = RRsetPtr(new RRset(Name::ROOT_NAME(),
  394. RRClass(mimpl->udpsize_),
  395. RRType::OPT(),
  396. RRTTL(extrcode_flags)));
  397. // We don't support any options in this simple implementation
  398. mimpl->local_edns_->addRdata(ConstRdataPtr(new generic::OPT()));
  399. mimpl->local_edns_->toWire(renderer);
  400. return (true);
  401. }
  402. }
  403. void
  404. Message::toWire(MessageRenderer& renderer)
  405. {
  406. uint16_t codes_and_flags;
  407. // reserve room for the header
  408. renderer.skip(HEADERLEN);
  409. uint16_t ancount = 0, nscount = 0, arcount = 0;
  410. uint16_t qdcount =
  411. for_each(impl_->questions_.begin(), impl_->questions_.end(),
  412. RenderSection<QuestionPtr>(renderer, false)).getTotalCount();
  413. // TBD: sort RRsets in each section based on configuration policy.
  414. if (!renderer.isTruncated()) {
  415. ancount =
  416. for_each(impl_->rrsets_[sectionCodeToId(Section::ANSWER())].begin(),
  417. impl_->rrsets_[sectionCodeToId(Section::ANSWER())].end(),
  418. RenderSection<RRsetPtr>(renderer, true)).getTotalCount();
  419. }
  420. if (!renderer.isTruncated()) {
  421. nscount =
  422. for_each(impl_->rrsets_[sectionCodeToId(Section::AUTHORITY())].begin(),
  423. impl_->rrsets_[sectionCodeToId(Section::AUTHORITY())].end(),
  424. RenderSection<RRsetPtr>(renderer, true)).getTotalCount();
  425. }
  426. if (renderer.isTruncated()) {
  427. setHeaderFlag(MessageFlag::TC());
  428. } else {
  429. arcount =
  430. for_each(impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].begin(),
  431. impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].end(),
  432. RenderSection<RRsetPtr>(renderer, false)).getTotalCount();
  433. }
  434. // Added EDNS OPT RR if necessary (we want to avoid hardcoding specialized
  435. // logic, see the parser case)
  436. if (!renderer.isTruncated() && addEDNS(this->impl_, renderer)) {
  437. ++arcount;
  438. }
  439. // TBD: TSIG, SIG(0) etc.
  440. // fill in the header
  441. size_t header_pos = 0;
  442. renderer.writeUint16At(impl_->qid_, header_pos);
  443. header_pos += sizeof(uint16_t);
  444. codes_and_flags = (impl_->opcode_->getCode() << OPCODE_SHIFT) & OPCODE_MASK;
  445. codes_and_flags |= (impl_->rcode_.getCode() & RCODE_MASK);
  446. codes_and_flags |= (impl_->flags_ & FLAG_MASK);
  447. renderer.writeUint16At(codes_and_flags, header_pos);
  448. header_pos += sizeof(uint16_t);
  449. // XXX: should avoid repeated pattern (TODO)
  450. renderer.writeUint16At(qdcount, header_pos);
  451. header_pos += sizeof(uint16_t);
  452. renderer.writeUint16At(ancount, header_pos);
  453. header_pos += sizeof(uint16_t);
  454. renderer.writeUint16At(nscount, header_pos);
  455. header_pos += sizeof(uint16_t);
  456. renderer.writeUint16At(arcount, header_pos);
  457. header_pos += sizeof(uint16_t);
  458. }
  459. void
  460. Message::fromWire(InputBuffer& buffer)
  461. {
  462. if ((buffer.getLength() - buffer.getPosition()) < HEADERLEN) {
  463. isc_throw(MessageTooShort, "");
  464. }
  465. impl_->qid_ = buffer.readUint16();
  466. uint16_t codes_and_flags = buffer.readUint16();
  467. impl_->opcode_ = opcodes[((codes_and_flags & OPCODE_MASK) >> OPCODE_SHIFT)];
  468. impl_->rcode_ = rcodes[(codes_and_flags & RCODE_MASK)];
  469. impl_->flags_ = (codes_and_flags & FLAG_MASK);
  470. impl_->counts_[Section::QUESTION().getCode()] = buffer.readUint16();
  471. impl_->counts_[Section::ANSWER().getCode()] = buffer.readUint16();
  472. impl_->counts_[Section::AUTHORITY().getCode()] = buffer.readUint16();
  473. impl_->counts_[Section::ADDITIONAL().getCode()] = buffer.readUint16();
  474. impl_->counts_[Section::QUESTION().getCode()] =
  475. impl_->parseQuestion(*this, buffer);
  476. impl_->counts_[Section::ANSWER().getCode()] =
  477. impl_->parseSection(*this, Section::ANSWER(), buffer);
  478. impl_->counts_[Section::AUTHORITY().getCode()] =
  479. impl_->parseSection(*this, Section::AUTHORITY(), buffer);
  480. impl_->counts_[Section::ADDITIONAL().getCode()] =
  481. impl_->parseSection(*this, Section::ADDITIONAL(), buffer);
  482. }
  483. int
  484. MessageImpl::parseQuestion(Message& message, InputBuffer& buffer)
  485. {
  486. unsigned int added = 0;
  487. for (unsigned int count = 0;
  488. count < counts_[Section::QUESTION().getCode()];
  489. count++) {
  490. Name name(buffer);
  491. if ((buffer.getLength() - buffer.getPosition()) <
  492. 2 * sizeof(uint16_t)) {
  493. isc_throw(MessageTooShort, "");
  494. }
  495. RRType rrtype(buffer.readUint16());
  496. RRClass rrclass(buffer.readUint16());
  497. // XXX: need a duplicate check. We might also want to have an optimized
  498. // algorithm that requires the question section contain exactly one
  499. // RR.
  500. questions_.push_back(QuestionPtr(new Question(name, rrclass, rrtype)));
  501. ++added;
  502. }
  503. return (added);
  504. }
  505. namespace {
  506. struct MatchRR : public unary_function<RRsetPtr, bool> {
  507. MatchRR(const Name& name, const RRType& rrtype, const RRClass& rrclass) :
  508. name_(name), rrtype_(rrtype), rrclass_(rrclass) {}
  509. bool operator()(const RRsetPtr& rrset) const
  510. {
  511. return (rrset->getType() == rrtype_ &&
  512. rrset->getClass() == rrclass_ &&
  513. rrset->getName() == name_);
  514. }
  515. const Name& name_;
  516. const RRType& rrtype_;
  517. const RRClass& rrclass_;
  518. };
  519. }
  520. int
  521. MessageImpl::parseSection(Message& message, const Section& section,
  522. InputBuffer& buffer)
  523. {
  524. unsigned int added = 0;
  525. for (unsigned int count = 0; count < counts_[section.getCode()]; count++) {
  526. Name name(buffer);
  527. // buffer must store at least RR TYPE, RR CLASS, TTL, and RDLEN.
  528. if ((buffer.getLength() - buffer.getPosition()) <
  529. 3 * sizeof(uint16_t) + sizeof(uint32_t)) {
  530. isc_throw(MessageTooShort, "");
  531. }
  532. RRType rrtype(buffer.readUint16());
  533. RRClass rrclass(buffer.readUint16());
  534. RRTTL ttl(buffer.readUint32());
  535. size_t rdlen = buffer.readUint16();
  536. RdataPtr rdata = createRdata(rrtype, rrclass, buffer, rdlen);
  537. // XXX: we wanted to avoid hardcoding type-specific logic here,
  538. // but this would be the fastest way for a proof-of-concept
  539. // implementation. We'll revisit this part later.
  540. if (rrtype == RRType::OPT()) {
  541. if (section != Section::ADDITIONAL()) {
  542. isc_throw(DNSMessageFORMERR,
  543. "EDNS OPT RR found in an invalid section");
  544. }
  545. if (remote_edns_ != NULL) {
  546. isc_throw(DNSMessageFORMERR, "multiple EDNS OPT RR found");
  547. }
  548. if (((ttl.getValue() & EDNSVERSION_MASK) >> 16) >
  549. Message::EDNS_SUPPORTED_VERSION) {
  550. // XXX: we should probably not reject the message yet, because
  551. // it's better to let the requestor know the responder-side
  552. // highest version as indicated in Section 4.6 of RFC2671.
  553. // This is probably because why BIND 9 does the version check
  554. // in the client code.
  555. // This is a TODO item. Right now we simply reject it.
  556. isc_throw(DNSMessageBADVERS, "unsupported EDNS version");
  557. }
  558. if (name != Name::ROOT_NAME()) {
  559. isc_throw(DNSMessageFORMERR,
  560. "invalid owner name for EDNS OPT RR");
  561. }
  562. remote_edns_ = RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
  563. remote_edns_->addRdata(rdata);
  564. dnssec_ok_ = (((ttl.getValue() & EXTFLAG_MASK) & EXTFLAG_DO) != 0);
  565. if (rrclass.getCode() > Message::DEFAULT_MAX_UDPSIZE) {
  566. udpsize_ = rrclass.getCode();
  567. }
  568. rcode_ = Rcode(((ttl.getValue() & EXTRCODE_MASK) >> 20) |
  569. rcode_.getCode());
  570. continue;
  571. }
  572. vector<RRsetPtr>::iterator it =
  573. find_if(rrsets_[sectionCodeToId(section)].begin(),
  574. rrsets_[sectionCodeToId(section)].end(),
  575. MatchRR(name, rrtype, rrclass));
  576. if (it != rrsets_[sectionCodeToId(section)].end()) {
  577. (*it)->setTTL(min((*it)->getTTL(), ttl));
  578. (*it)->addRdata(rdata);
  579. } else {
  580. RRsetPtr rrset = RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
  581. rrset->addRdata(rdata);
  582. rrsets_[sectionCodeToId(section)].push_back(rrset);
  583. }
  584. ++added;
  585. }
  586. return (added);
  587. }
  588. namespace {
  589. static const char *sectiontext[] = {
  590. "QUESTION",
  591. "ANSWER",
  592. "AUTHORITY",
  593. "ADDITIONAL"
  594. };
  595. template <typename T>
  596. struct SectionFormatter
  597. {
  598. SectionFormatter(const Section& section, string& output) :
  599. section_(section), output_(output) {}
  600. void operator()(const T& entry)
  601. {
  602. if (section_ == Section::QUESTION()) {
  603. output_ += ";";
  604. }
  605. output_ += entry->toText();
  606. }
  607. const Section& section_;
  608. string& output_;
  609. };
  610. }
  611. string
  612. Message::toText() const
  613. {
  614. string s;
  615. s += ";; ->>HEADER<<- opcode: " + impl_->opcode_->toText();
  616. // for simplicity we don't consider extended rcode (unlike BIND9)
  617. s += ", status: " + impl_->rcode_.toText();
  618. s += ", id: " + boost::lexical_cast<string>(impl_->qid_);
  619. s += "\n;; flags: ";
  620. if (getHeaderFlag(MessageFlag::QR()))
  621. s += "qr ";
  622. if (getHeaderFlag(MessageFlag::AA()))
  623. s += "aa ";
  624. if (getHeaderFlag(MessageFlag::TC()))
  625. s += "tc ";
  626. if (getHeaderFlag(MessageFlag::RD()))
  627. s += "rd ";
  628. if (getHeaderFlag(MessageFlag::RA()))
  629. s += "ra ";
  630. if (getHeaderFlag(MessageFlag::AD()))
  631. s += "ad ";
  632. if (getHeaderFlag(MessageFlag::CD()))
  633. s += "cd ";
  634. // for simplicity, don't consider the update case for now
  635. s += "; QUESTION: " +
  636. lexical_cast<string>(impl_->counts_[Section::QUESTION().getCode()]);
  637. s += ", ANSWER: " +
  638. lexical_cast<string>(impl_->counts_[Section::ANSWER().getCode()]);
  639. s += ", AUTHORITY: " +
  640. lexical_cast<string>(impl_->counts_[Section::AUTHORITY().getCode()]);
  641. unsigned int arcount = impl_->counts_[Section::ADDITIONAL().getCode()];
  642. RRsetPtr edns_rrset;
  643. if (!getHeaderFlag(MessageFlag::QR()) && impl_->remote_edns_ != NULL) {
  644. edns_rrset = impl_->remote_edns_;
  645. ++arcount;
  646. } else if (getHeaderFlag(MessageFlag::QR()) && impl_->local_edns_ != NULL) {
  647. edns_rrset = impl_->local_edns_;
  648. ++arcount;
  649. }
  650. s += ", ADDITIONAL: " + lexical_cast<string>(arcount) + "\n";
  651. if (edns_rrset != NULL) {
  652. s += "\n;; OPT PSEUDOSECTION:\n";
  653. s += "; EDNS: version: ";
  654. s += lexical_cast<string>(
  655. (edns_rrset->getTTL().getValue() & 0x00ff0000) >> 16);
  656. s += ", flags:";
  657. if ((edns_rrset->getTTL().getValue() & 0x8000) != 0) {
  658. s += " do";
  659. }
  660. uint32_t mbz = edns_rrset->getTTL().getValue() & ~0x8000 & 0xffff;
  661. if (mbz != 0) {
  662. s += "; MBZ: " + lexical_cast<string>(mbz) + ", udp: ";
  663. } else {
  664. s += "; udp: " +
  665. lexical_cast<string>(edns_rrset->getClass().getCode());
  666. }
  667. s += "\n";
  668. }
  669. if (!impl_->questions_.empty()) {
  670. s += "\n;; " +
  671. string(sectiontext[Section::QUESTION().getCode()]) + " SECTION:\n";
  672. for_each(impl_->questions_.begin(), impl_->questions_.end(),
  673. SectionFormatter<QuestionPtr>(Section::QUESTION(), s));
  674. }
  675. if (!impl_->rrsets_[sectionCodeToId(Section::ANSWER())].empty()) {
  676. s += "\n;; " +
  677. string(sectiontext[Section::ANSWER().getCode()]) + " SECTION:\n";
  678. for_each(impl_->rrsets_[sectionCodeToId(Section::ANSWER())].begin(),
  679. impl_->rrsets_[sectionCodeToId(Section::ANSWER())].end(),
  680. SectionFormatter<RRsetPtr>(Section::ANSWER(), s));
  681. }
  682. if (!impl_->rrsets_[sectionCodeToId(Section::AUTHORITY())].empty()) {
  683. s += "\n;; " +
  684. string(sectiontext[Section::AUTHORITY().getCode()]) + " SECTION:\n";
  685. for_each(impl_->rrsets_[sectionCodeToId(Section::AUTHORITY())].begin(),
  686. impl_->rrsets_[sectionCodeToId(Section::AUTHORITY())].end(),
  687. SectionFormatter<RRsetPtr>(Section::AUTHORITY(), s));
  688. }
  689. if (!impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].empty()) {
  690. s += "\n;; " +
  691. string(sectiontext[Section::ADDITIONAL().getCode()]) +
  692. " SECTION:\n";
  693. for_each(impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].begin(),
  694. impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].end(),
  695. SectionFormatter<RRsetPtr>(Section::ADDITIONAL(), s));
  696. }
  697. return (s);
  698. }
  699. void
  700. Message::clear(Mode mode)
  701. {
  702. impl_->init();
  703. impl_->mode_ = mode;
  704. }
  705. void
  706. Message::makeResponse()
  707. {
  708. if (impl_->mode_ != Message::PARSE) {
  709. isc_throw(InvalidMessageOperation,
  710. "makeResponse() is performed in non-parse mode");
  711. }
  712. impl_->dnssec_ok_ = false;
  713. impl_->remote_udpsize_ = impl_->udpsize_;
  714. impl_->local_edns_ = RRsetPtr();
  715. impl_->udpsize_ = DEFAULT_MAX_UDPSIZE;
  716. impl_->flags_ &= MESSAGE_REPLYPRESERVE;
  717. setHeaderFlag(MessageFlag::QR());
  718. impl_->mode_ = Message::RENDER;
  719. impl_->rrsets_[sectionCodeToId(Section::ANSWER())].clear();
  720. impl_->counts_[Section::ANSWER().getCode()] = 0;
  721. impl_->rrsets_[sectionCodeToId(Section::AUTHORITY())].clear();
  722. impl_->counts_[Section::AUTHORITY().getCode()] = 0;
  723. impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].clear();
  724. impl_->counts_[Section::ADDITIONAL().getCode()] = 0;
  725. }
  726. ///
  727. /// Template version of Section Iterator
  728. ///
  729. template <typename T>
  730. struct SectionIteratorImpl {
  731. SectionIteratorImpl(const typename vector<T>::const_iterator& it) :
  732. it_(it) {}
  733. typename vector<T>::const_iterator it_;
  734. };
  735. template <typename T>
  736. SectionIterator<T>::SectionIterator(const SectionIteratorImpl<T>& impl)
  737. {
  738. impl_ = new SectionIteratorImpl<T>(impl.it_);
  739. }
  740. template <typename T>
  741. SectionIterator<T>::~SectionIterator()
  742. {
  743. delete impl_;
  744. }
  745. template <typename T>
  746. SectionIterator<T>::SectionIterator(const SectionIterator<T>& source) :
  747. impl_(new SectionIteratorImpl<T>(source.impl_->it_))
  748. {}
  749. template <typename T>
  750. void
  751. SectionIterator<T>::operator=(const SectionIterator<T>& source)
  752. {
  753. if (impl_ == source.impl_) {
  754. return;
  755. }
  756. SectionIteratorImpl<T>* newimpl =
  757. new SectionIteratorImpl<T>(source.impl_->it_);
  758. delete impl_;
  759. impl_ = newimpl;
  760. }
  761. template <typename T>
  762. SectionIterator<T>&
  763. SectionIterator<T>::operator++()
  764. {
  765. ++(impl_->it_);
  766. return (*this);
  767. }
  768. template <typename T>
  769. SectionIterator<T>
  770. SectionIterator<T>::operator++(int)
  771. {
  772. SectionIterator<T> tmp(*this);
  773. ++(*this);
  774. return (tmp);
  775. }
  776. template <typename T>
  777. const T&
  778. SectionIterator<T>::operator*() const
  779. {
  780. return (*(impl_->it_));
  781. }
  782. template <typename T>
  783. const T*
  784. SectionIterator<T>::operator->() const
  785. {
  786. return (impl_->it_.operator->());
  787. }
  788. template <typename T>
  789. bool
  790. SectionIterator<T>::operator!=(const SectionIterator<T>& other) const
  791. {
  792. return (impl_->it_ != other.impl_->it_);
  793. }
  794. ///
  795. /// We need to explicitly instantiate these template classes because these
  796. /// are public classes but defined in this implementation file.
  797. ///
  798. template class SectionIterator<QuestionPtr>;
  799. template class SectionIterator<RRsetPtr>;
  800. namespace {
  801. typedef SectionIteratorImpl<QuestionPtr> QuestionIteratorImpl;
  802. typedef SectionIteratorImpl<RRsetPtr> RRsetIteratorImpl;
  803. }
  804. ///
  805. /// Question iterator
  806. ///
  807. const QuestionIterator
  808. Message::beginQuestion() const
  809. {
  810. return (QuestionIterator(QuestionIteratorImpl(impl_->questions_.begin())));
  811. }
  812. const QuestionIterator
  813. Message::endQuestion() const
  814. {
  815. return (QuestionIterator(QuestionIteratorImpl(impl_->questions_.end())));
  816. }
  817. ///
  818. /// RRsets iterators
  819. ///
  820. const SectionIterator<RRsetPtr>
  821. Message::beginSection(const Section& section) const
  822. {
  823. if (section == Section::QUESTION()) {
  824. isc_throw(InvalidMessageSection, "");
  825. }
  826. return (RRsetIterator(
  827. RRsetIteratorImpl(
  828. impl_->rrsets_[sectionCodeToId(section)].begin())));
  829. }
  830. const SectionIterator<RRsetPtr>
  831. Message::endSection(const Section& section) const
  832. {
  833. if (section == Section::QUESTION()) {
  834. isc_throw(InvalidMessageSection, "");
  835. }
  836. return (RRsetIterator(
  837. RRsetIteratorImpl(
  838. impl_->rrsets_[sectionCodeToId(section)].end())));
  839. }
  840. ostream&
  841. operator<<(ostream& os, const Opcode& opcode)
  842. {
  843. return (os << opcode.toText());
  844. }
  845. ostream&
  846. operator<<(ostream& os, const Rcode& rcode)
  847. {
  848. return (os << rcode.toText());
  849. }
  850. ostream&
  851. operator<<(ostream& os, const Message& message)
  852. {
  853. return (os << message.toText());
  854. }
  855. } // end of namespace dns
  856. } // end of namespace isc