response_scrubber_unittest.cc 21 KB

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