response_scrubber_unittest.cc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. // Copyright (C) 2011 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 <config.h>
  15. #include <string>
  16. #include <iostream>
  17. #include <gtest/gtest.h>
  18. #include <asiolink/io_endpoint.h>
  19. #include <asiolink/io_address.h>
  20. #include <netinet/in.h>
  21. #include <dns/name.h>
  22. #include <dns/opcode.h>
  23. #include <dns/question.h>
  24. #include <dns/rdata.h>
  25. #include <dns/rdataclass.h>
  26. #include <dns/rcode.h>
  27. #include <dns/rrclass.h>
  28. #include <dns/rrset.h>
  29. #include <dns/rrtype.h>
  30. #include <dns/rrttl.h>
  31. #include <resolver/response_scrubber.h>
  32. // Class for endpoint checks. The family of the endpoint is set in the
  33. // constructor; the address family by the string provided for the address.
  34. namespace isc {
  35. namespace asiolink {
  36. class GenericEndpoint : public IOEndpoint {
  37. public:
  38. GenericEndpoint(const std::string& address, uint16_t port, short protocol) :
  39. address_(address), port_(port), protocol_(protocol)
  40. {}
  41. virtual ~GenericEndpoint()
  42. {}
  43. virtual IOAddress getAddress() const {
  44. return address_;
  45. }
  46. virtual uint16_t getPort() const {
  47. return port_;
  48. }
  49. virtual short getProtocol() const {
  50. return protocol_;
  51. }
  52. virtual short getFamily() const {
  53. return address_.getFamily();
  54. }
  55. // This is completely dummy and unused. Define it just for build.
  56. virtual const struct sockaddr& getSockAddr() const {
  57. static struct sockaddr sa;
  58. return (sa);
  59. }
  60. private:
  61. IOAddress address_; // Address of endpoint
  62. uint16_t port_; // Port number of endpoint
  63. short protocol_; // Protocol of the endpoint
  64. };
  65. }
  66. }
  67. using namespace asio::ip;
  68. using namespace isc::dns;
  69. using namespace rdata;
  70. using namespace isc::dns::rdata::generic;
  71. using namespace isc::dns::rdata::in;
  72. using namespace isc::asiolink;
  73. // Test class
  74. namespace {
  75. class ResponseScrubberTest : public ::testing::Test {
  76. public:
  77. ResponseScrubberTest() :
  78. bailiwick("example.com"),
  79. qu_in_any_www(Name("www.example.com"), RRClass::IN(), RRType::ANY()),
  80. qu_in_a_www(Name("www.example.com"), RRClass::IN(), RRType::A()),
  81. qu_in_ns(Name("example.com"), RRClass::IN(), RRType::NS()),
  82. qu_in_txt_www(Name("www.example.com"), RRClass::IN(), RRType::TXT()),
  83. rrs_in_a_org(new RRset(Name("mail.example.org"), RRClass::IN(),
  84. RRType::A(), RRTTL(300))),
  85. rrs_in_a_net(new RRset(Name("mail.example.net"), RRClass::IN(),
  86. RRType::A(), RRTTL(300))),
  87. rrs_in_a_www(new RRset(Name("www.example.com"), RRClass::IN(),
  88. RRType::A(), RRTTL(300))),
  89. rrs_in_cname_www(new RRset(Name("www.example.com"), RRClass::IN(),
  90. RRType::CNAME(), RRTTL(300))),
  91. rrs_in_a_wwwnet(new RRset(Name("www.example.net"), RRClass::IN(),
  92. RRType::A(), RRTTL(300))),
  93. rrs_in_ns(new RRset(Name("example.com"), RRClass::IN(),
  94. RRType::NS(), RRTTL(300))),
  95. rrs_in_ns_com(new RRset(Name("com"), RRClass::IN(),
  96. RRType::NS(), RRTTL(300))),
  97. rrs_in_ns_net(new RRset(Name("example.net"), RRClass::IN(),
  98. RRType::NS(), RRTTL(300))),
  99. rrs_in_ns_sub(new RRset(Name("subdomain.example.com"), RRClass::IN(),
  100. RRType::NS(), RRTTL(300))),
  101. rrs_in_ns_sub2(new RRset(Name("subdomain2.example.com"), RRClass::IN(),
  102. RRType::NS(), RRTTL(300))),
  103. rrs_in_a_ns0(new RRset(Name("ns0.example.com"), RRClass::IN(),
  104. RRType::A(), RRTTL(300))),
  105. rrs_in_a_ns1(new RRset(Name("ns1.com"), RRClass::IN(),
  106. RRType::A(), RRTTL(300))),
  107. rrs_in_a_ns2(new RRset(Name("ns2.example.net"), RRClass::IN(),
  108. RRType::A(), RRTTL(300))),
  109. rrs_in_a_ns3(new RRset(Name("ns3.subdomain.example.com"), RRClass::IN(),
  110. RRType::A(), RRTTL(300))),
  111. rrs_in_txt_www(new RRset(Name("www.example.com"), RRClass::IN(),
  112. RRType::TXT(), RRTTL(300)))
  113. {}
  114. Name bailiwick; // Bailiwick of the server queried
  115. Question qu_in_any_www; // www.example.com IN ANY
  116. Question qu_in_a_www; // www.example.com IN A
  117. Question qu_in_ns; // example.com IN NS
  118. Question qu_in_txt_www; // www.example.com IN TXT
  119. RRsetPtr rrs_in_a_org; // mail.example.org IN A
  120. RRsetPtr rrs_in_a_net; // mail.example.org IN A
  121. RRsetPtr rrs_in_a_www; // www.example.com IN A
  122. RRsetPtr rrs_in_cname_www; // www.example.com IN CNAME
  123. RRsetPtr rrs_in_a_wwwnet; // www.example.net IN A
  124. RRsetPtr rrs_in_ns; // example.com IN NS
  125. RRsetPtr rrs_in_ns_com; // com IN NS
  126. RRsetPtr rrs_in_ns_net; // example.net IN NS
  127. RRsetPtr rrs_in_ns_sub; // subdomain.example.com IN NS
  128. RRsetPtr rrs_in_ns_sub2; // subdomain2.example.com IN NS
  129. RRsetPtr rrs_in_a_ns0; // ns0.example.com IN A
  130. RRsetPtr rrs_in_a_ns1; // ns1.com IN A
  131. RRsetPtr rrs_in_a_ns2; // ns2.example.net IN A
  132. RRsetPtr rrs_in_a_ns3; // ns3.subdomain.example.net IN A
  133. RRsetPtr rrs_in_txt_www; // www.example.com IN TXT
  134. };
  135. // Check that the IP addresses/ports/protocol for the packets sent and received
  136. // both match if both types are IP V4.
  137. TEST_F(ResponseScrubberTest, UDPv4) {
  138. // Basic UDP Endpoint
  139. GenericEndpoint udp_a("192.0.2.1", 12345, IPPROTO_UDP);
  140. // Same address, port
  141. GenericEndpoint udp_b("192.0.2.1", 12345, IPPROTO_UDP);
  142. EXPECT_EQ(ResponseScrubber::SUCCESS,
  143. ResponseScrubber::addressCheck(udp_a, udp_b));
  144. // Different address, same port
  145. GenericEndpoint udp_c("192.0.2.2", 12345, IPPROTO_UDP);
  146. EXPECT_EQ(ResponseScrubber::ADDRESS,
  147. ResponseScrubber::addressCheck(udp_a, udp_c));
  148. // Same address, different port
  149. GenericEndpoint udp_d("192.0.2.1", 12346, IPPROTO_UDP);
  150. EXPECT_EQ(ResponseScrubber::PORT,
  151. ResponseScrubber::addressCheck(udp_a, udp_d));
  152. // Different address, different port
  153. GenericEndpoint udp_e("192.0.2.3", 12347, IPPROTO_UDP);
  154. EXPECT_EQ(ResponseScrubber::ADDRESS,
  155. ResponseScrubber::addressCheck(udp_a, udp_e));
  156. }
  157. // Repeat the tests for TCP
  158. TEST_F(ResponseScrubberTest, TCPv4) {
  159. // Basic TCP Endpoint
  160. GenericEndpoint tcp_a("192.0.2.1", 12345, IPPROTO_TCP);
  161. // Same address, port
  162. GenericEndpoint tcp_b("192.0.2.1", 12345, IPPROTO_TCP);
  163. EXPECT_EQ(ResponseScrubber::SUCCESS,
  164. ResponseScrubber::addressCheck(tcp_a, tcp_b));
  165. // Different address, same port
  166. GenericEndpoint tcp_c("192.0.2.2", 12345, IPPROTO_TCP);
  167. EXPECT_EQ(ResponseScrubber::ADDRESS,
  168. ResponseScrubber::addressCheck(tcp_a, tcp_c));
  169. // Same address, different port
  170. GenericEndpoint tcp_d("192.0.2.1", 12346, IPPROTO_TCP);
  171. EXPECT_EQ(ResponseScrubber::PORT,
  172. ResponseScrubber::addressCheck(tcp_a, tcp_d));
  173. // Different address, different port
  174. GenericEndpoint tcp_e("192.0.2.3", 12347, IPPROTO_TCP);
  175. EXPECT_EQ(ResponseScrubber::ADDRESS,
  176. ResponseScrubber::addressCheck(tcp_a, tcp_e));
  177. }
  178. // Repeat the tests for UDP/IPv6
  179. TEST_F(ResponseScrubberTest, UDPv6) {
  180. // Basic UDP Endpoint
  181. GenericEndpoint udp_a("2001:db8::1", 12345, IPPROTO_UDP);
  182. // Same address and port
  183. GenericEndpoint udp_b("2001:db8::1", 12345, IPPROTO_UDP);
  184. EXPECT_EQ(ResponseScrubber::SUCCESS,
  185. ResponseScrubber::addressCheck(udp_a, udp_b));
  186. // Different address, same port
  187. GenericEndpoint udp_c("2001:db8::3", 12345, IPPROTO_UDP);
  188. EXPECT_EQ(ResponseScrubber::ADDRESS,
  189. ResponseScrubber::addressCheck(udp_a, udp_c));
  190. // Same address, different port
  191. GenericEndpoint udp_d("2001:db8::1", 12346, IPPROTO_UDP);
  192. EXPECT_EQ(ResponseScrubber::PORT,
  193. ResponseScrubber::addressCheck(udp_a, udp_d));
  194. // Different address, different port
  195. GenericEndpoint udp_e("2001:db8::3", 12347, IPPROTO_UDP);
  196. EXPECT_EQ(ResponseScrubber::ADDRESS,
  197. ResponseScrubber::addressCheck(udp_a, udp_e));
  198. }
  199. // Same again for TCP/IPv6
  200. TEST_F(ResponseScrubberTest, TCPv6) {
  201. // Basic TCP Endpoint
  202. GenericEndpoint tcp_a("2001:db8::1", 12345, IPPROTO_TCP);
  203. // Same address and port
  204. GenericEndpoint tcp_b("2001:db8::1", 12345, IPPROTO_TCP);
  205. EXPECT_EQ(ResponseScrubber::SUCCESS,
  206. ResponseScrubber::addressCheck(tcp_a, tcp_b));
  207. // Different address, same port
  208. GenericEndpoint tcp_c("2001:db8::3", 12345, IPPROTO_TCP);
  209. EXPECT_EQ(ResponseScrubber::ADDRESS,
  210. ResponseScrubber::addressCheck(tcp_a, tcp_c));
  211. // Same address, different port
  212. GenericEndpoint tcp_d("2001:db8::1", 12346, IPPROTO_TCP);
  213. EXPECT_EQ(ResponseScrubber::PORT,
  214. ResponseScrubber::addressCheck(tcp_a, tcp_d));
  215. // Different address, different port
  216. GenericEndpoint tcp_e("2001:db8::3", 12347, IPPROTO_TCP);
  217. EXPECT_EQ(ResponseScrubber::ADDRESS,
  218. ResponseScrubber::addressCheck(tcp_a, tcp_e));
  219. }
  220. // Ensure that mixed IPv4/6 addresses don't match.
  221. TEST_F(ResponseScrubberTest, v4v6) {
  222. // UDP
  223. GenericEndpoint udp_a("2001:db8::1", 12345, IPPROTO_UDP);
  224. GenericEndpoint udp_b("192.0.2.1", 12345, IPPROTO_UDP);
  225. EXPECT_EQ(ResponseScrubber::ADDRESS,
  226. ResponseScrubber::addressCheck(udp_a, udp_b));
  227. // TCP
  228. GenericEndpoint tcp_a("2001:db8::1", 12345, IPPROTO_TCP);
  229. GenericEndpoint tcp_b("192.0.2.1", 12345, IPPROTO_TCP);
  230. EXPECT_EQ(ResponseScrubber::ADDRESS,
  231. ResponseScrubber::addressCheck(udp_a, udp_b));
  232. }
  233. // Check mixed protocols are detected
  234. TEST_F(ResponseScrubberTest, Protocol) {
  235. GenericEndpoint udp_a("2001:db8::1", 12345, IPPROTO_UDP);
  236. GenericEndpoint tcp_a("2001:db8::1", 12345, IPPROTO_TCP);
  237. EXPECT_EQ(ResponseScrubber::PROTOCOL,
  238. ResponseScrubber::addressCheck(udp_a, tcp_a));
  239. }
  240. // Check that the QIDs check OK
  241. TEST_F(ResponseScrubberTest, Qid) {
  242. Message a(Message::RENDER);
  243. a.setQid(27);
  244. Message b(Message::RENDER);
  245. b.setQid(27);
  246. EXPECT_TRUE(ResponseScrubber::qidCheck(a, b));
  247. Message c(Message::RENDER);
  248. c.setQid(28);
  249. EXPECT_FALSE(ResponseScrubber::qidCheck(a, c));
  250. }
  251. // Check the scrubAllSections() method. As this operates by calling the
  252. // scrubSection() method (with a SUBDOMAIN argument), this is also a check of
  253. // the latter.
  254. TEST_F(ResponseScrubberTest, ScrubAllSectionsValid) {
  255. Message valid(Message::RENDER);
  256. // Valid message with nothing out of bailiwick
  257. valid.addQuestion(qu_in_a_www);
  258. valid.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
  259. valid.addRRset(Message::SECTION_AUTHORITY, rrs_in_ns);
  260. valid.addRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns0);
  261. // Scrub the message and expect nothing to have been removed.
  262. int removed = ResponseScrubber::scrubAllSections(valid, bailiwick);
  263. EXPECT_EQ(0, removed);
  264. // ... and check that this is the case
  265. EXPECT_TRUE(valid.hasRRset(Message::SECTION_ANSWER, rrs_in_a_www));
  266. EXPECT_TRUE(valid.hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns));
  267. EXPECT_TRUE(valid.hasRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns0));
  268. // Add out-of-bailiwick glue to the additional section (pretend that the
  269. // NS RRset contained an out-of-domain server.
  270. valid.addRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns2);
  271. EXPECT_TRUE(valid.hasRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns2));
  272. // ... and check that it is removed when scrubbed
  273. removed = ResponseScrubber::scrubAllSections(valid, bailiwick);
  274. EXPECT_EQ(1, removed);
  275. EXPECT_TRUE(valid.hasRRset(Message::SECTION_ANSWER, rrs_in_a_www));
  276. EXPECT_TRUE(valid.hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns));
  277. EXPECT_TRUE(valid.hasRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns0));
  278. EXPECT_FALSE(valid.hasRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns2));
  279. }
  280. TEST_F(ResponseScrubberTest, ScrubAllSectionsInvalid) {
  281. Message invalid(Message::RENDER);
  282. // Invalid message, with various things in and out of bailiwick.
  283. invalid.addQuestion(qu_in_a_www);
  284. // Answer section
  285. //
  286. // rrs_in_a_www - "www.example.com A", in bailiwick
  287. // rrs_in_txt_www - "www.example.com TXT", in bailiwick
  288. // rrs_in_a_org - "mail.example.org A", out of bailiwick - the qname is
  289. // related to the bailiwick name by having a common ancestor at the root
  290. // rrs_in_a_net - "mail.example.net A", out of bailiwick - the qname is
  291. // related to the bailiwick name by having a common ancestor at the root
  292. invalid.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
  293. invalid.addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
  294. invalid.addRRset(Message::SECTION_ANSWER, rrs_in_a_org);
  295. invalid.addRRset(Message::SECTION_ANSWER, rrs_in_a_net);
  296. // Authority section
  297. //
  298. // rrs_in_ns - "example.com NS", in bailiwick (qname is bailiwick name)
  299. // rrs_in_ns_com - "com NS", out of bailiwick as the qname is a superdomain
  300. // (direct ancestor) of the bailiwick name
  301. // rrs_in_ns_net - "example.net NS", out of bailiwick - the qname is related
  302. // to the bailiwick name by having a common ancestor at the root
  303. // rrs_in_ns_sub - "subdomain.example.com", in bailiwick as the qname is
  304. // a subdomain of the bailiwick name
  305. invalid.addRRset(Message::SECTION_AUTHORITY, rrs_in_ns);
  306. invalid.addRRset(Message::SECTION_AUTHORITY, rrs_in_ns_com);
  307. invalid.addRRset(Message::SECTION_AUTHORITY, rrs_in_ns_net);
  308. invalid.addRRset(Message::SECTION_AUTHORITY, rrs_in_ns_sub);
  309. // Additional section
  310. //
  311. // rrs_in_a_ns0 - "ns0.example.com", in bailiwick because the qname is
  312. // a subdomain of the bailiwick name
  313. // rrs_in_a_ns1 - "ns1.com", out of bailiwick because the qname is a
  314. // sibling to the bailiwick name
  315. // rrs_in_a_ns2 - "ns2.example.net", out of bailiwick because qname is
  316. // related by having a common ancestor and the root.
  317. // rrs_in_a_ns3 - "ns3.subdomain.example.com", in bailiwick because the
  318. // qname is a direct descendent of the bailiwick name.
  319. invalid.addRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns0);
  320. invalid.addRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns1);
  321. invalid.addRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns2);
  322. invalid.addRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns3);
  323. // Scrub the message
  324. int removed = ResponseScrubber::scrubAllSections(invalid, bailiwick);
  325. EXPECT_EQ(6, removed);
  326. // ... and check the sections. Answer...
  327. EXPECT_TRUE(invalid.hasRRset(Message::SECTION_ANSWER, rrs_in_a_www));
  328. EXPECT_TRUE(invalid.hasRRset(Message::SECTION_ANSWER, rrs_in_txt_www));
  329. EXPECT_FALSE(invalid.hasRRset(Message::SECTION_ANSWER, rrs_in_a_org));
  330. EXPECT_FALSE(invalid.hasRRset(Message::SECTION_ANSWER, rrs_in_a_net));
  331. // ... authority...
  332. EXPECT_TRUE(invalid.hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns));
  333. EXPECT_FALSE(invalid.hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns_com));
  334. EXPECT_FALSE(invalid.hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns_net));
  335. EXPECT_TRUE(invalid.hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns_sub));
  336. // ... additional.
  337. EXPECT_TRUE(invalid.hasRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns0));
  338. EXPECT_FALSE(invalid.hasRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns1));
  339. EXPECT_FALSE(invalid.hasRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns2));
  340. EXPECT_TRUE(invalid.hasRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns3));
  341. }
  342. // An empty message
  343. TEST_F(ResponseScrubberTest, ScrubAllSectionsEmpty) {
  344. Message empty(Message::RENDER);
  345. EXPECT_EQ(0, empty.getRRCount(Message::SECTION_QUESTION));
  346. EXPECT_EQ(0, empty.getRRCount(Message::SECTION_ANSWER));
  347. EXPECT_EQ(0, empty.getRRCount(Message::SECTION_AUTHORITY));
  348. EXPECT_EQ(0, empty.getRRCount(Message::SECTION_ADDITIONAL));
  349. int removed = ResponseScrubber::scrubAllSections(empty, bailiwick);
  350. EXPECT_EQ(0, removed);
  351. EXPECT_EQ(0, empty.getRRCount(Message::SECTION_QUESTION));
  352. EXPECT_EQ(0, empty.getRRCount(Message::SECTION_ANSWER));
  353. EXPECT_EQ(0, empty.getRRCount(Message::SECTION_AUTHORITY));
  354. EXPECT_EQ(0, empty.getRRCount(Message::SECTION_ADDITIONAL));
  355. }
  356. // Check the cross-section scrubbing (checks the general scrubSection()
  357. // method with a SUPERDOMAIN argument.)
  358. // Empty message (apart from question)
  359. TEST_F(ResponseScrubberTest, CrossSectionEmpty) {
  360. Message message1(Message::RENDER);
  361. message1.addQuestion(qu_in_a_www);
  362. int removed = ResponseScrubber::scrubCrossSections(message1);
  363. EXPECT_EQ(0, removed);
  364. }
  365. // Valid answer section
  366. TEST_F(ResponseScrubberTest, CrossSectionAnswer) {
  367. // Valid message with nothing out of bailiwick, but the authority
  368. // (subdomain.example.com) is not authoritative for the answer.
  369. //
  370. // TODO: Test the case where the additional section does not match
  371. // with something in the authority section.
  372. Message message1(Message::RENDER);
  373. message1.addQuestion(qu_in_a_www);
  374. message1.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
  375. message1.addRRset(Message::SECTION_AUTHORITY, rrs_in_ns_sub);
  376. message1.addRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns3);
  377. int removed = ResponseScrubber::scrubCrossSections(message1);
  378. EXPECT_EQ(1, removed);
  379. EXPECT_TRUE(message1.hasRRset(Message::SECTION_ANSWER, rrs_in_a_www));
  380. EXPECT_FALSE(message1.hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns_sub));
  381. EXPECT_TRUE(message1.hasRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns3));
  382. // A repeat of the test, this time with a mixture of incorrect and correct
  383. // authorities.
  384. Message message2(Message::RENDER);
  385. message2.addQuestion(qu_in_a_www);
  386. message2.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
  387. message2.addRRset(Message::SECTION_AUTHORITY, rrs_in_ns_sub);
  388. message2.addRRset(Message::SECTION_AUTHORITY, rrs_in_ns);
  389. message2.addRRset(Message::SECTION_AUTHORITY, rrs_in_ns_sub2);
  390. message2.addRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns3);
  391. removed = ResponseScrubber::scrubCrossSections(message2);
  392. EXPECT_EQ(2, removed);
  393. EXPECT_TRUE(message2.hasRRset(Message::SECTION_ANSWER, rrs_in_a_www));
  394. EXPECT_FALSE(message2.hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns_sub));
  395. EXPECT_TRUE(message2.hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns));
  396. EXPECT_FALSE(message2.hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns_sub2));
  397. EXPECT_TRUE(message2.hasRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns3));
  398. }
  399. // Test the main "scrub" method. This is a single to ensure that the
  400. // combination of methods
  401. TEST_F(ResponseScrubberTest, All) {
  402. MessagePtr mptr(new Message(Message::RENDER));
  403. // Question is "www.example.com IN A" sent to a nameserver with the
  404. // bailiwick of "example.com".
  405. mptr->addQuestion(qu_in_a_www);
  406. // Answer section.
  407. // "www.example.com IN CNAME www.example.net" - should be kept
  408. mptr->addRRset(Message::SECTION_ANSWER, rrs_in_cname_www);
  409. // "www.example.net IN A a.b.c.d" - should be removed, out of bailiwick
  410. mptr->addRRset(Message::SECTION_ANSWER, rrs_in_a_wwwnet);
  411. // Authority section.
  412. // "example.net IN NS xxxx" - should be removed, out of bailiwick.
  413. mptr->addRRset(Message::SECTION_AUTHORITY, rrs_in_ns_net);
  414. // "example.com IN NS xxx" - kept
  415. mptr->addRRset(Message::SECTION_AUTHORITY, rrs_in_ns);
  416. // "com IN NS xxx" - removed, out of bailiwick
  417. mptr->addRRset(Message::SECTION_AUTHORITY, rrs_in_ns_com);
  418. // "subdomain.example.com IN NS xxx" - removed, not a superdomain of the
  419. // answer.
  420. mptr->addRRset(Message::SECTION_AUTHORITY, rrs_in_ns_sub);
  421. // Additional section
  422. // "ns2.example.net IN A a.b.c.d" - removed, out of bailiwick
  423. mptr->addRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns2);
  424. // "ns3.subdomain.example.com IN A a.b.c.d" - retained.
  425. mptr->addRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns3);
  426. unsigned int removed = ResponseScrubber::scrub(mptr, bailiwick);
  427. EXPECT_EQ(5, removed);
  428. EXPECT_TRUE(mptr->hasRRset(Message::SECTION_ANSWER, rrs_in_cname_www));
  429. EXPECT_FALSE(mptr->hasRRset(Message::SECTION_ANSWER, rrs_in_a_wwwnet));
  430. EXPECT_FALSE(mptr->hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns_net));
  431. EXPECT_TRUE(mptr->hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns));
  432. EXPECT_FALSE(mptr->hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns_com));
  433. EXPECT_FALSE(mptr->hasRRset(Message::SECTION_AUTHORITY, rrs_in_ns_sub));
  434. EXPECT_FALSE(mptr->hasRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns2));
  435. EXPECT_TRUE(mptr->hasRRset(Message::SECTION_ADDITIONAL, rrs_in_a_ns3));
  436. }
  437. } // Anonymous namespace