statistics_unittest.cc.pre 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  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 <config.h>
  15. #include <gtest/gtest.h>
  16. #include <boost/bind.hpp>
  17. #include <dns/opcode.h>
  18. #include <dns/rcode.h>
  19. #include <dns/rrttl.h>
  20. #include <cc/data.h>
  21. #include <auth/statistics.h>
  22. #include <auth/statistics_items.h>
  23. #include <dns/tests/unittest_util.h>
  24. #include "statistics_util.h"
  25. #include <unistd.h>
  26. #include <sys/types.h>
  27. #include <sys/socket.h>
  28. #include <netinet/in.h>
  29. #include <netdb.h>
  30. using namespace std;
  31. using namespace isc::dns;
  32. using namespace isc::data;
  33. using namespace isc::auth::statistics;
  34. using namespace isc::auth::unittest;
  35. namespace {
  36. // ### STATISTICS ITEMS DEFINITION ###
  37. class CountersTest : public ::testing::Test {
  38. protected:
  39. CountersTest() : counters() {}
  40. ~CountersTest() {}
  41. Counters counters;
  42. };
  43. void
  44. buildSkeletonMessage(MessageAttributes& msgattrs) {
  45. msgattrs.setRequestIPVersion(AF_INET);
  46. msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
  47. msgattrs.setRequestOpCode(Opcode::QUERY());
  48. msgattrs.setRequestEDNS0(true);
  49. msgattrs.setRequestDO(true);
  50. }
  51. TEST_F(CountersTest, invalidParameterForSetRequestIPVersion) {
  52. MessageAttributes msgattrs;
  53. // It should not throw if the parameter is AF_INET or AF_INET6.
  54. EXPECT_NO_THROW(msgattrs.setRequestIPVersion(AF_INET));
  55. EXPECT_NO_THROW(msgattrs.setRequestIPVersion(AF_INET6));
  56. // It should throw isc::InvalidParameter if the parameter is not AF_INET
  57. // nor AF_INET6.
  58. EXPECT_THROW(msgattrs.setRequestIPVersion(AF_UNIX), isc::InvalidParameter);
  59. }
  60. TEST_F(CountersTest, invalidParameterForSetRequestTransportProtocol) {
  61. MessageAttributes msgattrs;
  62. // It should not throw if the parameter is IPPROTO_UDP or IPPROTO_TCP.
  63. EXPECT_NO_THROW(msgattrs.setRequestTransportProtocol(IPPROTO_UDP));
  64. EXPECT_NO_THROW(msgattrs.setRequestTransportProtocol(IPPROTO_TCP));
  65. // It should throw isc::InvalidParameter if the parameter is not
  66. // IPPROTO_UDP nor IPPROTO_TCP.
  67. EXPECT_THROW(msgattrs.setRequestTransportProtocol(IPPROTO_IP),
  68. isc::InvalidParameter);
  69. }
  70. TEST_F(CountersTest, invalidOperationForGetRequestOpCode) {
  71. MessageAttributes msgattrs;
  72. // getRequestOpCode() should return boost::none when called before
  73. // opcode is set with setRequestOpCode().
  74. EXPECT_FALSE(msgattrs.getRequestOpCode());
  75. msgattrs.setRequestOpCode(Opcode::QUERY());
  76. // getRequestOpCode() should be Opcode::QUERY.
  77. EXPECT_EQ(Opcode::QUERY(), msgattrs.getRequestOpCode().get());
  78. }
  79. TEST_F(CountersTest, invalidParameterForSetRequestTSIG) {
  80. MessageAttributes msgattrs;
  81. // These patterns should not throw:
  82. // request signature badsig
  83. // --------------------------
  84. // (none) false
  85. // TSIG false
  86. // TSIG true
  87. EXPECT_NO_THROW(msgattrs.setRequestTSIG(false, false));
  88. EXPECT_NO_THROW(msgattrs.setRequestTSIG(true, false));
  89. EXPECT_NO_THROW(msgattrs.setRequestTSIG(true, true));
  90. // It should throw isc::InvalidParameter if a message is not signed but
  91. // badsig is true
  92. EXPECT_THROW(msgattrs.setRequestTSIG(false, true), isc::InvalidParameter);
  93. }
  94. TEST_F(CountersTest, incrementResponse) {
  95. Message response(Message::RENDER);
  96. MessageAttributes msgattrs;
  97. std::map<std::string, int> expect;
  98. // Test response counters are incremented only if responded == true.
  99. for (int i = 0; i < 2; ++i) {
  100. const bool responded = i & 1;
  101. buildSkeletonMessage(msgattrs);
  102. response.setRcode(Rcode::REFUSED());
  103. response.addQuestion(Question(Name("example.com"),
  104. RRClass::IN(), RRType::AAAA()));
  105. response.setHeaderFlag(Message::HEADERFLAG_QR);
  106. counters.inc(msgattrs, response, responded);
  107. expect.clear();
  108. expect["opcode.query"] = i+1;
  109. expect["request.v4"] = i+1;
  110. expect["request.udp"] = i+1;
  111. expect["request.edns0"] = i+1;
  112. expect["request.badednsver"] = 0;
  113. expect["request.dnssec_ok"] = i+1;
  114. expect["responses"] = responded ? 1 : 0;
  115. expect["qrynoauthans"] = responded ? 1 : 0;
  116. expect["rcode.refused"] = responded ? 1 : 0;
  117. expect["authqryrej"] = responded ? 1 : 0;
  118. checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
  119. expect);
  120. }
  121. }
  122. TEST_F(CountersTest, incrementProtocolType) {
  123. Message response(Message::RENDER);
  124. MessageAttributes msgattrs;
  125. std::map<std::string, int> expect;
  126. // Test these patterns:
  127. // af proto
  128. // -----------------
  129. // ipv6 tcp
  130. // ipv4 tcp
  131. // ipv6 udp
  132. // ipv4 udp
  133. int count_v4 = 0, count_v6 = 0, count_udp = 0, count_tcp = 0;
  134. for (int i = 0; i < 4; ++i) {
  135. const int af = i & 1 ? AF_INET : AF_INET6;
  136. const int proto = i & 2 ? IPPROTO_UDP : IPPROTO_TCP;
  137. buildSkeletonMessage(msgattrs);
  138. msgattrs.setRequestIPVersion(af);
  139. msgattrs.setRequestTransportProtocol(proto);
  140. response.setRcode(Rcode::REFUSED());
  141. response.addQuestion(Question(Name("example.com"),
  142. RRClass::IN(), RRType::AAAA()));
  143. response.setHeaderFlag(Message::HEADERFLAG_QR);
  144. counters.inc(msgattrs, response, true);
  145. if (af == AF_INET) {
  146. ++count_v4;
  147. } else {
  148. ++count_v6;
  149. }
  150. if (proto == IPPROTO_UDP) {
  151. ++count_udp;
  152. } else {
  153. ++count_tcp;
  154. }
  155. expect.clear();
  156. expect["opcode.query"] = i+1;
  157. expect["request.v4"] = count_v4;
  158. expect["request.v6"] = count_v6;
  159. expect["request.udp"] = count_udp;
  160. expect["request.tcp"] = count_tcp;
  161. expect["request.edns0"] = i+1;
  162. expect["request.badednsver"] = 0;
  163. expect["request.dnssec_ok"] = i+1;
  164. expect["responses"] = i+1;
  165. expect["qrynoauthans"] = i+1;
  166. expect["rcode.refused"] = i+1;
  167. expect["authqryrej"] = i+1;
  168. checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
  169. expect);
  170. }
  171. }
  172. TEST_F(CountersTest, incrementDO) {
  173. Message response(Message::RENDER);
  174. MessageAttributes msgattrs;
  175. std::map<std::string, int> expect;
  176. // Test these patterns:
  177. // DNSSEC OK
  178. // -----------
  179. // false
  180. // true
  181. for (int i = 0; i < 2; ++i) {
  182. const bool is_dnssec_ok = i & 1;
  183. buildSkeletonMessage(msgattrs);
  184. msgattrs.setRequestDO(is_dnssec_ok);
  185. response.setRcode(Rcode::REFUSED());
  186. response.addQuestion(Question(Name("example.com"),
  187. RRClass::IN(), RRType::AAAA()));
  188. response.setHeaderFlag(Message::HEADERFLAG_QR);
  189. counters.inc(msgattrs, response, true);
  190. expect.clear();
  191. expect["opcode.query"] = i+1;
  192. expect["request.v4"] = i+1;
  193. expect["request.udp"] = i+1;
  194. expect["request.edns0"] = i+1;
  195. expect["request.badednsver"] = 0;
  196. expect["request.dnssec_ok"] = i & 1;
  197. expect["responses"] = i+1;
  198. expect["qrynoauthans"] = i+1;
  199. expect["rcode.refused"] = i+1;
  200. expect["authqryrej"] = i+1;
  201. checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
  202. expect);
  203. }
  204. }
  205. TEST_F(CountersTest, incrementEDNS) {
  206. Message response(Message::RENDER);
  207. MessageAttributes msgattrs;
  208. std::map<std::string, int> expect;
  209. // Test these patterns:
  210. // request edns0 response edns0
  211. // --------------------------------
  212. // false true
  213. // true false
  214. //
  215. // They can't be both true since edns0 and badednsver are exclusive.
  216. int count_req_edns0 = 0, count_res_edns0 = 0;
  217. for (int i = 0; i < 2; ++i) {
  218. const bool is_edns0 = i & 1;
  219. buildSkeletonMessage(msgattrs);
  220. msgattrs.setRequestEDNS0(is_edns0);
  221. if (!is_edns0) {
  222. ConstEDNSPtr edns = EDNSPtr(new EDNS(0));
  223. response.setEDNS(edns);
  224. } else {
  225. response.setEDNS(EDNSPtr());
  226. }
  227. response.setRcode(Rcode::REFUSED());
  228. response.addQuestion(Question(Name("example.com"),
  229. RRClass::IN(), RRType::AAAA()));
  230. response.setHeaderFlag(Message::HEADERFLAG_QR);
  231. counters.inc(msgattrs, response, true);
  232. if (is_edns0) {
  233. ++count_req_edns0;
  234. } else {
  235. ++count_res_edns0;
  236. }
  237. expect.clear();
  238. expect["opcode.query"] = i+1;
  239. expect["request.v4"] = i+1;
  240. expect["request.udp"] = i+1;
  241. expect["request.edns0"] = count_req_edns0;
  242. expect["response.edns0"] = count_res_edns0;
  243. expect["request.badednsver"] = 0;
  244. expect["request.dnssec_ok"] = i+1;
  245. expect["responses"] = i+1;
  246. expect["qrynoauthans"] = i+1;
  247. expect["rcode.refused"] = i+1;
  248. expect["authqryrej"] = i+1;
  249. checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
  250. expect);
  251. }
  252. }
  253. TEST_F(CountersTest, incrementTSIG) {
  254. Message response(Message::RENDER);
  255. MessageAttributes msgattrs;
  256. std::map<std::string, int> expect;
  257. // Test these patterns:
  258. // request signature badsig response signature
  259. // -----------------------------------------------
  260. // (none) false (none)
  261. // TSIG false TSIG
  262. // TSIG true (none)
  263. //
  264. // badsig can't be true if the message does not have signature.
  265. int count_req_tsig = 0, count_res_tsig = 0, count_badsig = 0;
  266. for (int i = 0; i < 3; ++i) {
  267. const bool is_req_tsig = (i == 2) ? true : (i & 1) != 0;
  268. const bool is_res_tsig = (i & 1) != 0;
  269. const bool is_badsig = (i & 2) != 0;
  270. buildSkeletonMessage(msgattrs);
  271. msgattrs.setRequestTSIG(is_req_tsig, is_badsig);
  272. msgattrs.setResponseTSIG(is_res_tsig);
  273. response.setRcode(Rcode::REFUSED());
  274. response.addQuestion(Question(Name("example.com"),
  275. RRClass::IN(), RRType::AAAA()));
  276. response.setHeaderFlag(Message::HEADERFLAG_QR);
  277. // don't increment response counters if signature is bad
  278. counters.inc(msgattrs, response, !is_badsig);
  279. if (is_req_tsig) {
  280. ++count_req_tsig;
  281. }
  282. if (is_res_tsig) {
  283. ++count_res_tsig;
  284. }
  285. if (is_badsig) {
  286. ++count_badsig;
  287. }
  288. expect.clear();
  289. expect["request.v4"] = i+1;
  290. expect["request.udp"] = i+1;
  291. expect["opcode.query"] = i+1;
  292. expect["request.edns0"] = i+1 - count_badsig;
  293. expect["request.badednsver"] = 0;
  294. expect["request.dnssec_ok"] = i+1 - count_badsig;
  295. expect["request.tsig"] = count_req_tsig;
  296. expect["response.tsig"] = count_res_tsig;
  297. expect["request.sig0"] = 0;
  298. expect["request.badsig"] = count_badsig;
  299. expect["responses"] = i+1 - count_badsig;
  300. expect["qrynoauthans"] = i+1 - count_badsig;
  301. expect["rcode.refused"] = i+1 - count_badsig;
  302. expect["authqryrej"] = i+1 - count_badsig;
  303. checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
  304. expect);
  305. }
  306. }
  307. TEST_F(CountersTest, incrementOpcode) {
  308. Message response(Message::RENDER);
  309. MessageAttributes msgattrs;
  310. std::map<std::string, int> expect;
  311. // Test all opcodes (QUERY..RESERVED15)
  312. int count_all = 0, count_opcode_other = 0;
  313. for (uint8_t i = Opcode::QUERY().getCode(),
  314. e = Opcode::RESERVED15().getCode();
  315. i <= e;
  316. ++i)
  317. {
  318. buildSkeletonMessage(msgattrs);
  319. msgattrs.setRequestOpCode(Opcode(i));
  320. msgattrs.setRequestTSIG(false, false);
  321. response.setRcode(Rcode::REFUSED());
  322. response.addQuestion(Question(Name("example.com"),
  323. RRClass::IN(), RRType::AAAA()));
  324. response.setHeaderFlag(Message::HEADERFLAG_QR);
  325. for (uint8_t j = 0; j < i; ++j) {
  326. // count up i times for i-th opcode to identify counters
  327. counters.inc(msgattrs, response, true);
  328. ++count_all;
  329. }
  330. expect.clear();
  331. expect["request.v4"] = count_all;
  332. expect["request.udp"] = count_all;
  333. expect["request.edns0"] = count_all;
  334. expect["request.badednsver"] = 0;
  335. expect["request.dnssec_ok"] = count_all;
  336. expect["request.tsig"] = 0;
  337. expect["request.sig0"] = 0;
  338. expect["request.badsig"] = 0;
  339. expect["responses"] = count_all;
  340. expect["rcode.refused"] = count_all;
  341. if (opcode_to_msgcounter[i] == MSG_OPCODE_OTHER) {
  342. count_opcode_other += i;
  343. }
  344. for (uint8_t j = 0; j <= i; ++j) {
  345. if (opcode_to_msgcounter[j] == MSG_OPCODE_OTHER) {
  346. expect["opcode.other"] = count_opcode_other;
  347. } else {
  348. std::string code_text = Opcode(j).toText();
  349. std::transform(code_text.begin(), code_text.end(),
  350. code_text.begin(), ::tolower);
  351. expect["opcode."+code_text] = j;
  352. }
  353. }
  354. checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
  355. expect);
  356. }
  357. }
  358. TEST_F(CountersTest, incrementRcode) {
  359. Message response(Message::RENDER);
  360. MessageAttributes msgattrs;
  361. std::map<std::string, int> expect;
  362. // Test all rcodes (NOERROR..BADVERS)
  363. int count_all = 0, count_rcode_other = 0, count_ednsbadver = 0;
  364. for (uint16_t i = Rcode::NOERROR().getCode(),
  365. e = Rcode::BADVERS().getCode();
  366. i <= e;
  367. ++i)
  368. {
  369. buildSkeletonMessage(msgattrs);
  370. msgattrs.setRequestOpCode(Opcode::IQUERY());
  371. msgattrs.setRequestTSIG(false, false);
  372. response.setRcode(Rcode(i));
  373. response.addQuestion(Question(Name("example.com"),
  374. RRClass::IN(), RRType::AAAA()));
  375. response.setHeaderFlag(Message::HEADERFLAG_QR);
  376. for (uint16_t j = 0; j < i; ++j) {
  377. // count up i times for i-th rcode to identify counters
  378. counters.inc(msgattrs, response, true);
  379. ++count_all;
  380. }
  381. expect.clear();
  382. expect["opcode.iquery"] = count_all;
  383. expect["request.v4"] = count_all;
  384. expect["request.udp"] = count_all;
  385. expect["request.edns0"] = count_all;
  386. expect["request.dnssec_ok"] = count_all;
  387. expect["request.tsig"] = 0;
  388. expect["request.sig0"] = 0;
  389. expect["request.badsig"] = 0;
  390. expect["responses"] = count_all;
  391. if (rcode_to_msgcounter[i] == MSG_RCODE_OTHER) {
  392. count_rcode_other += i;
  393. }
  394. // "request.badednsver" counts for Rcode == BADVERS
  395. if (rcode_to_msgcounter[i] == MSG_RCODE_BADVERS) {
  396. count_ednsbadver += i;
  397. }
  398. expect["request.badednsver"] = count_ednsbadver;
  399. for (uint16_t j = 0; j <= i; ++j) {
  400. if (rcode_to_msgcounter[j] == MSG_RCODE_OTHER) {
  401. expect["rcode.other"] = count_rcode_other;
  402. } else {
  403. std::string code_text = Rcode(j).toText();
  404. std::transform(code_text.begin(), code_text.end(),
  405. code_text.begin(), ::tolower);
  406. expect["rcode."+code_text] = j;
  407. }
  408. }
  409. checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
  410. expect);
  411. }
  412. }
  413. TEST_F(CountersTest, incrementTruncated) {
  414. Message response(Message::RENDER);
  415. MessageAttributes msgattrs;
  416. std::map<std::string, int> expect;
  417. // Test these patterns:
  418. // truncated
  419. // -----------
  420. // false
  421. // true
  422. int count_truncated = 0;
  423. for (int i = 0; i < 2; ++i) {
  424. const bool is_truncated = i & 1;
  425. buildSkeletonMessage(msgattrs);
  426. msgattrs.setRequestOpCode(Opcode::IQUERY());
  427. msgattrs.setRequestTSIG(false, false);
  428. msgattrs.setResponseTruncated(is_truncated);
  429. response.setRcode(Rcode::SERVFAIL());
  430. response.addQuestion(Question(Name("example.com"),
  431. RRClass::IN(), RRType::TXT()));
  432. response.setHeaderFlag(Message::HEADERFLAG_QR);
  433. counters.inc(msgattrs, response, true);
  434. if (is_truncated) {
  435. ++count_truncated;
  436. }
  437. expect.clear();
  438. expect["opcode.iquery"] = i+1;
  439. expect["request.v4"] = i+1;
  440. expect["request.udp"] = i+1;
  441. expect["request.edns0"] = i+1;
  442. expect["request.dnssec_ok"] = i+1;
  443. expect["responses"] = i+1;
  444. expect["rcode.servfail"] = i+1;
  445. expect["response.truncated"] = count_truncated;
  446. checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
  447. expect);
  448. }
  449. }
  450. TEST_F(CountersTest, incrementQryAuthAnsAndNoAuthAns) {
  451. Message response(Message::RENDER);
  452. MessageAttributes msgattrs;
  453. std::map<std::string, int> expect;
  454. // Opcode = QUERY, ANCOUNT = 0 (don't care), Rcode = SERVFAIL (don't care)
  455. // Test these patterns:
  456. // AA flag
  457. // -----------------------
  458. // false -> QryNoAuthAns
  459. // true -> QryAuthAns
  460. int count_authans = 0, count_noauthans = 0;
  461. for (int i = 0; i < 2; ++i) {
  462. const bool is_aa_set = i & 1;
  463. buildSkeletonMessage(msgattrs);
  464. msgattrs.setRequestTSIG(false, false);
  465. response.setRcode(Rcode::SERVFAIL());
  466. response.addQuestion(Question(Name("example.com"),
  467. RRClass::IN(), RRType::TXT()));
  468. response.setHeaderFlag(Message::HEADERFLAG_QR);
  469. if (is_aa_set) {
  470. response.setHeaderFlag(Message::HEADERFLAG_AA);
  471. ++count_authans;
  472. } else {
  473. ++count_noauthans;
  474. }
  475. counters.inc(msgattrs, response, true);
  476. expect.clear();
  477. expect["opcode.query"] = i+1;
  478. expect["request.v4"] = i+1;
  479. expect["request.udp"] = i+1;
  480. expect["request.edns0"] = i+1;
  481. expect["request.dnssec_ok"] = i+1;
  482. expect["responses"] = i+1;
  483. expect["rcode.servfail"] = i+1;
  484. expect["qryauthans"] = count_authans;
  485. expect["qrynoauthans"] = count_noauthans;
  486. checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
  487. expect);
  488. }
  489. }
  490. TEST_F(CountersTest, incrementQrySuccess) {
  491. Message response(Message::RENDER);
  492. MessageAttributes msgattrs;
  493. std::map<std::string, int> expect;
  494. // Opcode = QUERY, Rcode = NOERROR, ANCOUNT > 0
  495. msgattrs.setRequestIPVersion(AF_INET);
  496. msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
  497. msgattrs.setRequestOpCode(Opcode::QUERY());
  498. msgattrs.setRequestEDNS0(true);
  499. msgattrs.setRequestDO(true);
  500. msgattrs.setRequestTSIG(false, false);
  501. response.setRcode(Rcode::NOERROR());
  502. response.addQuestion(Question(Name("example.com"),
  503. RRClass::IN(), RRType::TXT()));
  504. RRsetPtr answer_rrset(new RRset(Name("example.com"),
  505. RRClass::IN(), RRType::TXT(),
  506. RRTTL(3600)));
  507. answer_rrset->addRdata(rdata::createRdata(RRType::TXT(),
  508. RRClass::IN(),
  509. "Answer"));
  510. response.addRRset(Message::SECTION_ANSWER, answer_rrset);
  511. response.setHeaderFlag(Message::HEADERFLAG_QR);
  512. counters.inc(msgattrs, response, true);
  513. expect.clear();
  514. expect["opcode.query"] = 1;
  515. expect["request.v4"] = 1;
  516. expect["request.udp"] = 1;
  517. expect["request.edns0"] = 1;
  518. expect["request.dnssec_ok"] = 1;
  519. expect["responses"] = 1;
  520. expect["rcode.noerror"] = 1;
  521. expect["qrysuccess"] = 1;
  522. // noauthans is also incremented
  523. expect["qrynoauthans"] = 1;
  524. checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
  525. expect);
  526. }
  527. TEST_F(CountersTest, incrementQryReferralAndNxrrset) {
  528. Message response(Message::RENDER);
  529. MessageAttributes msgattrs;
  530. std::map<std::string, int> expect;
  531. // Opcode = QUERY, Rcode = NOERROR, ANCOUNT = 0
  532. // Test these patterns:
  533. // AA flag
  534. // ----------------------
  535. // false -> QryReferral
  536. // true -> QryNxrrset
  537. int count_referral = 0, count_nxrrset = 0;
  538. for (int i = 0; i < 2; ++i) {
  539. const bool is_aa_set = i & 1;
  540. msgattrs.setRequestIPVersion(AF_INET);
  541. msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
  542. msgattrs.setRequestOpCode(Opcode::QUERY());
  543. msgattrs.setRequestEDNS0(true);
  544. msgattrs.setRequestDO(true);
  545. msgattrs.setRequestTSIG(false, false);
  546. response.setRcode(Rcode::NOERROR());
  547. response.addQuestion(Question(Name("example.com"),
  548. RRClass::IN(), RRType::TXT()));
  549. response.setHeaderFlag(Message::HEADERFLAG_QR);
  550. if (is_aa_set) {
  551. response.setHeaderFlag(Message::HEADERFLAG_AA);
  552. ++count_nxrrset;
  553. } else {
  554. ++count_referral;
  555. }
  556. counters.inc(msgattrs, response, true);
  557. expect.clear();
  558. expect["opcode.query"] = i+1;
  559. expect["request.v4"] = i+1;
  560. expect["request.udp"] = i+1;
  561. expect["request.edns0"] = i+1;
  562. expect["request.dnssec_ok"] = i+1;
  563. expect["responses"] = i+1;
  564. expect["rcode.noerror"] = i+1;
  565. expect["qrynxrrset"] = count_nxrrset;
  566. expect["qryreferral"] = count_referral;
  567. // qryauthans or qrynoauthans is also incremented
  568. expect["qryauthans"] = count_nxrrset;
  569. expect["qrynoauthans"] = count_referral;
  570. checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
  571. expect);
  572. }
  573. }
  574. TEST_F(CountersTest, incrementAuthQryRej) {
  575. Message response(Message::RENDER);
  576. MessageAttributes msgattrs;
  577. std::map<std::string, int> expect;
  578. // Opcode = QUERY, Rcode = REFUSED, ANCOUNT = 0 (don't care)
  579. msgattrs.setRequestIPVersion(AF_INET);
  580. msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
  581. msgattrs.setRequestOpCode(Opcode::QUERY());
  582. msgattrs.setRequestEDNS0(true);
  583. msgattrs.setRequestDO(true);
  584. msgattrs.setRequestTSIG(false, false);
  585. response.setRcode(Rcode::REFUSED());
  586. response.addQuestion(Question(Name("example.com"),
  587. RRClass::IN(), RRType::TXT()));
  588. response.setHeaderFlag(Message::HEADERFLAG_QR);
  589. counters.inc(msgattrs, response, true);
  590. expect.clear();
  591. expect["opcode.query"] = 1;
  592. expect["request.v4"] = 1;
  593. expect["request.udp"] = 1;
  594. expect["request.edns0"] = 1;
  595. expect["request.dnssec_ok"] = 1;
  596. expect["responses"] = 1;
  597. expect["rcode.refused"] = 1;
  598. expect["authqryrej"] = 1;
  599. // noauthans is also incremented since AA bit is not set
  600. expect["qrynoauthans"] = 1;
  601. checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
  602. expect);
  603. }
  604. int
  605. countTreeElements(const struct CounterSpec* tree) {
  606. int count = 0;
  607. for (int i = 0; tree[i].name != NULL; ++i) {
  608. if (tree[i].sub_counters == NULL) {
  609. ++count;
  610. } else {
  611. count += countTreeElements(tree[i].sub_counters);
  612. }
  613. }
  614. return (count);
  615. }
  616. TEST(StatisticsItemsTest, MSGItemNamesCheck) {
  617. EXPECT_EQ(MSG_COUNTER_TYPES, countTreeElements(msg_counter_tree));
  618. }
  619. }