statistics_unittest.cc.pre 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  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_CODE);
  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_CODE);
  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_CODE);
  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_CODE);
  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. // SIG(0) false
  264. // SIG(0) true
  265. //
  266. // badsig can't be true if the message does not have signature.
  267. int count_req_tsig = 0, count_res_tsig = 0, count_req_sig0 = 0,
  268. count_badsig = 0;
  269. for (int i = 0; i < 5; ++i) {
  270. const bool is_tsig = (i == 0 ? i : i+1) & 2;
  271. const bool is_sig0 = (i == 0 ? i : i+1) & 4;
  272. const bool is_badsig = (i == 0 ? i : i+1) & 1;
  273. msgattrs.setRequestIPVersion(AF_INET);
  274. msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
  275. msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
  276. msgattrs.setRequestEDNS0(true);
  277. msgattrs.setRequestDO(true);
  278. msgattrs.setRequestSig(is_tsig, is_sig0, is_badsig);
  279. response.setRcode(Rcode::REFUSED());
  280. response.addQuestion(Question(Name("example.com"),
  281. RRClass::IN(), RRType::AAAA()));
  282. response.setHeaderFlag(Message::HEADERFLAG_QR);
  283. // don't increment response counters if signature is bad
  284. counters.inc(msgattrs, response, !is_badsig);
  285. if (is_tsig) {
  286. ++count_req_tsig;
  287. if (!is_badsig) {
  288. ++count_res_tsig;
  289. }
  290. }
  291. if (is_sig0) {
  292. ++count_req_sig0;
  293. }
  294. if (is_badsig) {
  295. ++count_badsig;
  296. }
  297. expect.clear();
  298. expect["request.v4"] = i+1;
  299. expect["request.udp"] = i+1;
  300. expect["opcode.query"] = i+1 - count_badsig;
  301. expect["request.edns0"] = i+1 - count_badsig;
  302. expect["request.badednsver"] = 0;
  303. expect["request.dnssec_ok"] = i+1 - count_badsig;
  304. expect["request.tsig"] = count_req_tsig;
  305. expect["response.tsig"] = count_res_tsig;
  306. expect["request.sig0"] = count_req_sig0;
  307. expect["request.badsig"] = count_badsig;
  308. expect["responses"] = i+1 - count_badsig;
  309. expect["qrynoauthans"] = i+1 - count_badsig;
  310. expect["rcode.refused"] = i+1 - count_badsig;
  311. expect["authqryrej"] = i+1 - count_badsig;
  312. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  313. }
  314. }
  315. TEST_F(CountersTest, incrementOpcode) {
  316. Message response(Message::RENDER);
  317. MessageAttributes msgattrs;
  318. std::map<std::string, int> expect;
  319. // Test all opcodes (QUERY..RESERVED15)
  320. int count_all = 0, count_opcode_other = 0;
  321. for (uint8_t i = Opcode::QUERY().getCode(),
  322. e = Opcode::RESERVED15().getCode();
  323. i <= e;
  324. ++i)
  325. {
  326. msgattrs.setRequestIPVersion(AF_INET);
  327. msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
  328. msgattrs.setRequestOpCode(i);
  329. msgattrs.setRequestEDNS0(true);
  330. msgattrs.setRequestDO(true);
  331. msgattrs.setRequestSig(false, false, false);
  332. response.setRcode(Rcode::REFUSED());
  333. response.addQuestion(Question(Name("example.com"),
  334. RRClass::IN(), RRType::AAAA()));
  335. response.setHeaderFlag(Message::HEADERFLAG_QR);
  336. for (uint8_t j = 0; j < i; ++j) {
  337. // count up i times for i-th opcode to identify counters
  338. counters.inc(msgattrs, response, true);
  339. ++count_all;
  340. }
  341. expect.clear();
  342. expect["request.v4"] = count_all;
  343. expect["request.udp"] = count_all;
  344. expect["request.edns0"] = count_all;
  345. expect["request.badednsver"] = 0;
  346. expect["request.dnssec_ok"] = count_all;
  347. expect["request.tsig"] = 0;
  348. expect["request.sig0"] = 0;
  349. expect["request.badsig"] = 0;
  350. expect["responses"] = count_all;
  351. expect["rcode.refused"] = count_all;
  352. if (opcode_to_msgcounter[i] == MSG_OPCODE_OTHER) {
  353. count_opcode_other += i;
  354. }
  355. for (uint8_t j = 0; j <= i; ++j) {
  356. if (opcode_to_msgcounter[j] == MSG_OPCODE_OTHER) {
  357. expect["opcode.other"] = count_opcode_other;
  358. } else {
  359. std::string code_text = Opcode(j).toText();
  360. std::transform(code_text.begin(), code_text.end(),
  361. code_text.begin(), ::tolower);
  362. expect["opcode."+code_text] = j;
  363. }
  364. }
  365. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  366. }
  367. }
  368. TEST_F(CountersTest, incrementRcode) {
  369. Message response(Message::RENDER);
  370. MessageAttributes msgattrs;
  371. std::map<std::string, int> expect;
  372. // Test all rcodes (NOERROR..BADVERS)
  373. int count_all = 0, count_rcode_other = 0, count_ednsbadver = 0;
  374. for (uint16_t i = Rcode::NOERROR().getCode(),
  375. e = Rcode::BADVERS().getCode();
  376. i <= e;
  377. ++i)
  378. {
  379. msgattrs.setRequestIPVersion(AF_INET);
  380. msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
  381. msgattrs.setRequestOpCode(Opcode::IQUERY_CODE);
  382. msgattrs.setRequestEDNS0(true);
  383. msgattrs.setRequestDO(true);
  384. msgattrs.setRequestSig(false, false, false);
  385. response.setRcode(Rcode(i));
  386. response.addQuestion(Question(Name("example.com"),
  387. RRClass::IN(), RRType::AAAA()));
  388. response.setHeaderFlag(Message::HEADERFLAG_QR);
  389. for (uint16_t j = 0; j < i; ++j) {
  390. // count up i times for i-th rcode to identify counters
  391. counters.inc(msgattrs, response, true);
  392. ++count_all;
  393. }
  394. expect.clear();
  395. expect["opcode.iquery"] = count_all;
  396. expect["request.v4"] = count_all;
  397. expect["request.udp"] = count_all;
  398. expect["request.edns0"] = count_all;
  399. expect["request.dnssec_ok"] = count_all;
  400. expect["request.tsig"] = 0;
  401. expect["request.sig0"] = 0;
  402. expect["request.badsig"] = 0;
  403. expect["responses"] = count_all;
  404. if (rcode_to_msgcounter[i] == MSG_RCODE_OTHER) {
  405. count_rcode_other += i;
  406. }
  407. // "request.badednsver" counts for Rcode == BADVERS
  408. if (rcode_to_msgcounter[i] == MSG_RCODE_BADVERS) {
  409. count_ednsbadver += i;
  410. }
  411. expect["request.badednsver"] = count_ednsbadver;
  412. for (uint16_t j = 0; j <= i; ++j) {
  413. if (rcode_to_msgcounter[j] == MSG_RCODE_OTHER) {
  414. expect["rcode.other"] = count_rcode_other;
  415. } else {
  416. std::string code_text = Rcode(j).toText();
  417. std::transform(code_text.begin(), code_text.end(),
  418. code_text.begin(), ::tolower);
  419. expect["rcode."+code_text] = j;
  420. }
  421. }
  422. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  423. }
  424. }
  425. TEST_F(CountersTest, incrementTruncated) {
  426. Message response(Message::RENDER);
  427. MessageAttributes msgattrs;
  428. std::map<std::string, int> expect;
  429. // Test these patterns:
  430. // truncated
  431. // -----------
  432. // false
  433. // true
  434. int count_truncated = 0;
  435. for (int i = 0; i < 2; ++i) {
  436. const bool is_truncated = i & 1;
  437. msgattrs.setRequestIPVersion(AF_INET);
  438. msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
  439. msgattrs.setRequestOpCode(Opcode::IQUERY_CODE);
  440. msgattrs.setRequestEDNS0(true);
  441. msgattrs.setRequestDO(true);
  442. msgattrs.setRequestSig(false, false, false);
  443. msgattrs.setResponseTruncated(is_truncated);
  444. response.setRcode(Rcode::SERVFAIL());
  445. response.addQuestion(Question(Name("example.com"),
  446. RRClass::IN(), RRType::TXT()));
  447. response.setHeaderFlag(Message::HEADERFLAG_QR);
  448. counters.inc(msgattrs, response, true);
  449. if (is_truncated) {
  450. ++count_truncated;
  451. }
  452. expect.clear();
  453. expect["opcode.iquery"] = i+1;
  454. expect["request.v4"] = i+1;
  455. expect["request.udp"] = i+1;
  456. expect["request.edns0"] = i+1;
  457. expect["request.dnssec_ok"] = i+1;
  458. expect["responses"] = i+1;
  459. expect["rcode.servfail"] = i+1;
  460. expect["response.truncated"] = count_truncated;
  461. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  462. }
  463. }
  464. TEST_F(CountersTest, incrementQryAuthAnsAndNoAuthAns) {
  465. Message response(Message::RENDER);
  466. MessageAttributes msgattrs;
  467. std::map<std::string, int> expect;
  468. // Opcode = QUERY, ANCOUNT = 0 (don't care), Rcode = SERVFAIL (don't care)
  469. // Test these patterns:
  470. // AA flag
  471. // -----------------------
  472. // false -> QryNoAuthAns
  473. // true -> QryAuthAns
  474. int count_authans = 0, count_noauthans = 0;
  475. for (int i = 0; i < 2; ++i) {
  476. const bool is_aa_set = i & 1;
  477. msgattrs.setRequestIPVersion(AF_INET);
  478. msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
  479. msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
  480. msgattrs.setRequestEDNS0(true);
  481. msgattrs.setRequestDO(true);
  482. msgattrs.setRequestSig(false, false, false);
  483. response.setRcode(Rcode::SERVFAIL());
  484. response.addQuestion(Question(Name("example.com"),
  485. RRClass::IN(), RRType::TXT()));
  486. response.setHeaderFlag(Message::HEADERFLAG_QR);
  487. if (is_aa_set) {
  488. response.setHeaderFlag(Message::HEADERFLAG_AA);
  489. ++count_authans;
  490. } else {
  491. ++count_noauthans;
  492. }
  493. counters.inc(msgattrs, response, true);
  494. expect.clear();
  495. expect["opcode.query"] = i+1;
  496. expect["request.v4"] = i+1;
  497. expect["request.udp"] = i+1;
  498. expect["request.edns0"] = i+1;
  499. expect["request.dnssec_ok"] = i+1;
  500. expect["responses"] = i+1;
  501. expect["rcode.servfail"] = i+1;
  502. expect["qryauthans"] = count_authans;
  503. expect["qrynoauthans"] = count_noauthans;
  504. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  505. }
  506. }
  507. TEST_F(CountersTest, incrementQrySuccess) {
  508. Message response(Message::RENDER);
  509. MessageAttributes msgattrs;
  510. std::map<std::string, int> expect;
  511. // Opcode = QUERY, Rcode = NOERROR, ANCOUNT > 0
  512. msgattrs.setRequestIPVersion(AF_INET);
  513. msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
  514. msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
  515. msgattrs.setRequestEDNS0(true);
  516. msgattrs.setRequestDO(true);
  517. msgattrs.setRequestSig(false, false, false);
  518. response.setRcode(Rcode::NOERROR());
  519. response.addQuestion(Question(Name("example.com"),
  520. RRClass::IN(), RRType::TXT()));
  521. RRsetPtr answer_rrset(new RRset(Name("example.com"),
  522. RRClass::IN(), RRType::TXT(),
  523. RRTTL(3600)));
  524. answer_rrset->addRdata(rdata::createRdata(RRType::TXT(),
  525. RRClass::IN(),
  526. "Answer"));
  527. response.addRRset(Message::SECTION_ANSWER, answer_rrset);
  528. response.setHeaderFlag(Message::HEADERFLAG_QR);
  529. counters.inc(msgattrs, response, true);
  530. expect.clear();
  531. expect["opcode.query"] = 1;
  532. expect["request.v4"] = 1;
  533. expect["request.udp"] = 1;
  534. expect["request.edns0"] = 1;
  535. expect["request.dnssec_ok"] = 1;
  536. expect["responses"] = 1;
  537. expect["rcode.noerror"] = 1;
  538. expect["qrysuccess"] = 1;
  539. // noauthans is also incremented
  540. expect["qrynoauthans"] = 1;
  541. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  542. }
  543. TEST_F(CountersTest, incrementQryReferralAndNxrrset) {
  544. Message response(Message::RENDER);
  545. MessageAttributes msgattrs;
  546. std::map<std::string, int> expect;
  547. // Opcode = QUERY, Rcode = NOERROR, ANCOUNT = 0
  548. // Test these patterns:
  549. // AA flag
  550. // ----------------------
  551. // false -> QryReferral
  552. // true -> QryNxrrset
  553. int count_referral = 0, count_nxrrset = 0;
  554. for (int i = 0; i < 2; ++i) {
  555. const bool is_aa_set = i & 1;
  556. msgattrs.setRequestIPVersion(AF_INET);
  557. msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
  558. msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
  559. msgattrs.setRequestEDNS0(true);
  560. msgattrs.setRequestDO(true);
  561. msgattrs.setRequestSig(false, false, false);
  562. response.setRcode(Rcode::NOERROR());
  563. response.addQuestion(Question(Name("example.com"),
  564. RRClass::IN(), RRType::TXT()));
  565. response.setHeaderFlag(Message::HEADERFLAG_QR);
  566. if (is_aa_set) {
  567. response.setHeaderFlag(Message::HEADERFLAG_AA);
  568. ++count_nxrrset;
  569. } else {
  570. ++count_referral;
  571. }
  572. counters.inc(msgattrs, response, true);
  573. expect.clear();
  574. expect["opcode.query"] = i+1;
  575. expect["request.v4"] = i+1;
  576. expect["request.udp"] = i+1;
  577. expect["request.edns0"] = i+1;
  578. expect["request.dnssec_ok"] = i+1;
  579. expect["responses"] = i+1;
  580. expect["rcode.noerror"] = i+1;
  581. expect["qrynxrrset"] = count_nxrrset;
  582. expect["qryreferral"] = count_referral;
  583. // qryauthans or qrynoauthans is also incremented
  584. expect["qryauthans"] = count_nxrrset;
  585. expect["qrynoauthans"] = count_referral;
  586. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  587. }
  588. }
  589. TEST_F(CountersTest, incrementAuthQryRej) {
  590. Message response(Message::RENDER);
  591. MessageAttributes msgattrs;
  592. std::map<std::string, int> expect;
  593. // Opcode = QUERY, Rcode = REFUSED, ANCOUNT = 0 (don't care)
  594. msgattrs.setRequestIPVersion(AF_INET);
  595. msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
  596. msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
  597. msgattrs.setRequestEDNS0(true);
  598. msgattrs.setRequestDO(true);
  599. msgattrs.setRequestSig(false, false, false);
  600. response.setRcode(Rcode::REFUSED());
  601. response.addQuestion(Question(Name("example.com"),
  602. RRClass::IN(), RRType::TXT()));
  603. response.setHeaderFlag(Message::HEADERFLAG_QR);
  604. counters.inc(msgattrs, response, true);
  605. expect.clear();
  606. expect["opcode.query"] = 1;
  607. expect["request.v4"] = 1;
  608. expect["request.udp"] = 1;
  609. expect["request.edns0"] = 1;
  610. expect["request.dnssec_ok"] = 1;
  611. expect["responses"] = 1;
  612. expect["rcode.refused"] = 1;
  613. expect["authqryrej"] = 1;
  614. // noauthans is also incremented since AA bit is not set
  615. expect["qrynoauthans"] = 1;
  616. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  617. }
  618. int
  619. countTreeElements(const struct CounterSpec* tree) {
  620. int count = 0;
  621. for (int i = 0; tree[i].name != NULL; ++i) {
  622. if (tree[i].sub_counters == NULL) {
  623. ++count;
  624. } else {
  625. count += countTreeElements(tree[i].sub_counters);
  626. }
  627. }
  628. return (count);
  629. }
  630. TEST(StatisticsItemsTest, MSGItemNamesCheck) {
  631. EXPECT_EQ(MSG_COUNTER_TYPES, countTreeElements(msg_counter_tree));
  632. }
  633. }