statistics_unittest.cc.pre 24 KB

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