statistics_unittest.cc.pre 23 KB

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