statistics_unittest.cc.pre 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  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. void
  87. buildSkeletonMessage(MessageAttributes& msgattrs) {
  88. msgattrs.setRequestIPVersion(MessageAttributes::IP_VERSION_IPV4);
  89. msgattrs.setRequestTransportProtocol(MessageAttributes::TRANSPORT_UDP);
  90. msgattrs.setRequestOpCode(Opcode::QUERY());
  91. msgattrs.setRequestEDNS0(true);
  92. msgattrs.setRequestDO(true);
  93. }
  94. TEST_F(CountersTest, invalidParameter) {
  95. MessageAttributes msgattrs;
  96. // Passing *_UNSPEC should trigger an assertion failure.
  97. // Note that we just check that it dies - we don't check what message is
  98. // output.
  99. EXPECT_DEATH_IF_SUPPORTED(
  100. msgattrs.setRequestIPVersion(MessageAttributes::IP_VERSION_UNSPEC),
  101. ".*");
  102. EXPECT_DEATH_IF_SUPPORTED(
  103. msgattrs.setRequestTransportProtocol(
  104. MessageAttributes::TRANSPORT_UNSPEC),
  105. ".*");
  106. }
  107. TEST_F(CountersTest, invalidOperationForGetRequestOpCode) {
  108. MessageAttributes msgattrs;
  109. // getRequestOpCode() will throw isc::InvalidOperation when called before
  110. // opcode is set with setRequestOpCode().
  111. EXPECT_THROW(msgattrs.getRequestOpCode(), isc::InvalidOperation);
  112. msgattrs.setRequestOpCode(Opcode::QUERY());
  113. // getRequestOpCode() will not throw at this point.
  114. EXPECT_NO_THROW(msgattrs.getRequestOpCode());
  115. }
  116. TEST_F(CountersTest, incrementResponse) {
  117. Message response(Message::RENDER);
  118. MessageAttributes msgattrs;
  119. std::map<std::string, int> expect;
  120. // Test response counters are incremented only if responded == true.
  121. for (int i = 0; i < 2; ++i) {
  122. const bool responded = i & 1;
  123. buildSkeletonMessage(msgattrs);
  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, responded);
  129. expect.clear();
  130. expect["opcode.query"] = i+1;
  131. expect["request.v4"] = i+1;
  132. expect["request.udp"] = i+1;
  133. expect["request.edns0"] = i+1;
  134. expect["request.badednsver"] = 0;
  135. expect["request.dnssec_ok"] = i+1;
  136. expect["responses"] = responded ? 1 : 0;
  137. expect["qrynoauthans"] = responded ? 1 : 0;
  138. expect["rcode.refused"] = responded ? 1 : 0;
  139. expect["authqryrej"] = responded ? 1 : 0;
  140. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  141. }
  142. }
  143. TEST_F(CountersTest, incrementProtocolType) {
  144. Message response(Message::RENDER);
  145. MessageAttributes msgattrs;
  146. std::map<std::string, int> expect;
  147. // Test these patterns:
  148. // ipversion protocol
  149. // -----------------
  150. // ipv4 udp
  151. // ipv6 udp
  152. // ipv4 tcp
  153. // ipv6 tcp
  154. int count_v4 = 0, count_v6 = 0, count_udp = 0, count_tcp = 0;
  155. for (int i = 0; i < 4; ++i) {
  156. const enum MessageAttributes::IPVersion ipversion = (i & 1) != 0 ?
  157. MessageAttributes::IP_VERSION_IPV4 :
  158. MessageAttributes::IP_VERSION_IPV6;
  159. const enum MessageAttributes::TransportProtocol proto = (i & 2) != 0 ?
  160. MessageAttributes::TRANSPORT_UDP :
  161. MessageAttributes::TRANSPORT_TCP;
  162. buildSkeletonMessage(msgattrs);
  163. msgattrs.setRequestIPVersion(ipversion);
  164. msgattrs.setRequestTransportProtocol(proto);
  165. response.setRcode(Rcode::REFUSED());
  166. response.addQuestion(Question(Name("example.com"),
  167. RRClass::IN(), RRType::AAAA()));
  168. response.setHeaderFlag(Message::HEADERFLAG_QR);
  169. counters.inc(msgattrs, response, true);
  170. if (ipversion == MessageAttributes::IP_VERSION_IPV4) {
  171. ++count_v4;
  172. } else {
  173. ++count_v6;
  174. }
  175. if (proto == MessageAttributes::TRANSPORT_UDP) {
  176. ++count_udp;
  177. } else {
  178. ++count_tcp;
  179. }
  180. expect.clear();
  181. expect["opcode.query"] = i+1;
  182. expect["request.v4"] = count_v4;
  183. expect["request.v6"] = count_v6;
  184. expect["request.udp"] = count_udp;
  185. expect["request.tcp"] = count_tcp;
  186. expect["request.edns0"] = i+1;
  187. expect["request.badednsver"] = 0;
  188. expect["request.dnssec_ok"] = i+1;
  189. expect["responses"] = i+1;
  190. expect["qrynoauthans"] = i+1;
  191. expect["rcode.refused"] = i+1;
  192. expect["authqryrej"] = i+1;
  193. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  194. }
  195. }
  196. TEST_F(CountersTest, incrementDO) {
  197. Message response(Message::RENDER);
  198. MessageAttributes msgattrs;
  199. std::map<std::string, int> expect;
  200. // Test these patterns:
  201. // DNSSEC OK
  202. // -----------
  203. // false
  204. // true
  205. for (int i = 0; i < 2; ++i) {
  206. const bool is_dnssec_ok = i & 1;
  207. buildSkeletonMessage(msgattrs);
  208. msgattrs.setRequestDO(is_dnssec_ok);
  209. response.setRcode(Rcode::REFUSED());
  210. response.addQuestion(Question(Name("example.com"),
  211. RRClass::IN(), RRType::AAAA()));
  212. response.setHeaderFlag(Message::HEADERFLAG_QR);
  213. counters.inc(msgattrs, response, true);
  214. expect.clear();
  215. expect["opcode.query"] = i+1;
  216. expect["request.v4"] = i+1;
  217. expect["request.udp"] = i+1;
  218. expect["request.edns0"] = i+1;
  219. expect["request.badednsver"] = 0;
  220. expect["request.dnssec_ok"] = i & 1;
  221. expect["responses"] = i+1;
  222. expect["qrynoauthans"] = i+1;
  223. expect["rcode.refused"] = i+1;
  224. expect["authqryrej"] = i+1;
  225. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  226. }
  227. }
  228. TEST_F(CountersTest, incrementEDNS) {
  229. Message response(Message::RENDER);
  230. MessageAttributes msgattrs;
  231. std::map<std::string, int> expect;
  232. // Test these patterns:
  233. // request edns0 response edns0
  234. // --------------------------------
  235. // false true
  236. // true false
  237. //
  238. // They can't be both true since edns0 and badednsver are exclusive.
  239. int count_req_edns0 = 0, count_res_edns0 = 0;
  240. for (int i = 0; i < 2; ++i) {
  241. const bool is_edns0 = i & 1;
  242. buildSkeletonMessage(msgattrs);
  243. msgattrs.setRequestEDNS0(is_edns0);
  244. if (!is_edns0) {
  245. ConstEDNSPtr edns = EDNSPtr(new EDNS(0));
  246. response.setEDNS(edns);
  247. } else {
  248. response.setEDNS(EDNSPtr());
  249. }
  250. response.setRcode(Rcode::REFUSED());
  251. response.addQuestion(Question(Name("example.com"),
  252. RRClass::IN(), RRType::AAAA()));
  253. response.setHeaderFlag(Message::HEADERFLAG_QR);
  254. counters.inc(msgattrs, response, true);
  255. if (is_edns0) {
  256. ++count_req_edns0;
  257. } else {
  258. ++count_res_edns0;
  259. }
  260. expect.clear();
  261. expect["opcode.query"] = i+1;
  262. expect["request.v4"] = i+1;
  263. expect["request.udp"] = i+1;
  264. expect["request.edns0"] = count_req_edns0;
  265. expect["response.edns0"] = count_res_edns0;
  266. expect["request.badednsver"] = 0;
  267. expect["request.dnssec_ok"] = i+1;
  268. expect["responses"] = i+1;
  269. expect["qrynoauthans"] = i+1;
  270. expect["rcode.refused"] = i+1;
  271. expect["authqryrej"] = i+1;
  272. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  273. }
  274. }
  275. TEST_F(CountersTest, incrementTSIG) {
  276. Message response(Message::RENDER);
  277. MessageAttributes msgattrs;
  278. std::map<std::string, int> expect;
  279. // Test these patterns:
  280. // request signature badsig response signature
  281. // -----------------------------------------------
  282. // (none) false (none)
  283. // TSIG false TSIG
  284. // TSIG true (none)
  285. //
  286. // badsig can't be true if the message does not have signature.
  287. int count_req_tsig = 0, count_res_tsig = 0, count_badsig = 0;
  288. for (int i = 0; i < 3; ++i) {
  289. const bool is_req_tsig = (i == 2) ? true : (i & 1) != 0;
  290. const bool is_res_tsig = (i & 1) != 0;
  291. const bool is_badsig = (i & 2) != 0;
  292. buildSkeletonMessage(msgattrs);
  293. msgattrs.setRequestSig(is_req_tsig, is_badsig);
  294. msgattrs.setResponseSigTSIG(is_res_tsig);
  295. response.setRcode(Rcode::REFUSED());
  296. response.addQuestion(Question(Name("example.com"),
  297. RRClass::IN(), RRType::AAAA()));
  298. response.setHeaderFlag(Message::HEADERFLAG_QR);
  299. // don't increment response counters if signature is bad
  300. counters.inc(msgattrs, response, !is_badsig);
  301. if (is_req_tsig) {
  302. ++count_req_tsig;
  303. }
  304. if (is_res_tsig) {
  305. ++count_res_tsig;
  306. }
  307. if (is_badsig) {
  308. ++count_badsig;
  309. }
  310. expect.clear();
  311. expect["request.v4"] = i+1;
  312. expect["request.udp"] = i+1;
  313. expect["opcode.query"] = i+1 - count_badsig;
  314. expect["request.edns0"] = i+1 - count_badsig;
  315. expect["request.badednsver"] = 0;
  316. expect["request.dnssec_ok"] = i+1 - count_badsig;
  317. expect["request.tsig"] = count_req_tsig;
  318. expect["response.tsig"] = count_res_tsig;
  319. expect["request.sig0"] = 0;
  320. expect["request.badsig"] = count_badsig;
  321. expect["responses"] = i+1 - count_badsig;
  322. expect["qrynoauthans"] = i+1 - count_badsig;
  323. expect["rcode.refused"] = i+1 - count_badsig;
  324. expect["authqryrej"] = i+1 - count_badsig;
  325. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  326. }
  327. }
  328. TEST_F(CountersTest, incrementOpcode) {
  329. Message response(Message::RENDER);
  330. MessageAttributes msgattrs;
  331. std::map<std::string, int> expect;
  332. // Test all opcodes (QUERY..RESERVED15)
  333. int count_all = 0, count_opcode_other = 0;
  334. for (uint8_t i = Opcode::QUERY().getCode(),
  335. e = Opcode::RESERVED15().getCode();
  336. i <= e;
  337. ++i)
  338. {
  339. buildSkeletonMessage(msgattrs);
  340. msgattrs.setRequestOpCode(Opcode(i));
  341. msgattrs.setRequestSig(false, false);
  342. response.setRcode(Rcode::REFUSED());
  343. response.addQuestion(Question(Name("example.com"),
  344. RRClass::IN(), RRType::AAAA()));
  345. response.setHeaderFlag(Message::HEADERFLAG_QR);
  346. for (uint8_t j = 0; j < i; ++j) {
  347. // count up i times for i-th opcode to identify counters
  348. counters.inc(msgattrs, response, true);
  349. ++count_all;
  350. }
  351. expect.clear();
  352. expect["request.v4"] = count_all;
  353. expect["request.udp"] = count_all;
  354. expect["request.edns0"] = count_all;
  355. expect["request.badednsver"] = 0;
  356. expect["request.dnssec_ok"] = count_all;
  357. expect["request.tsig"] = 0;
  358. expect["request.sig0"] = 0;
  359. expect["request.badsig"] = 0;
  360. expect["responses"] = count_all;
  361. expect["rcode.refused"] = count_all;
  362. if (opcode_to_msgcounter[i] == MSG_OPCODE_OTHER) {
  363. count_opcode_other += i;
  364. }
  365. for (uint8_t j = 0; j <= i; ++j) {
  366. if (opcode_to_msgcounter[j] == MSG_OPCODE_OTHER) {
  367. expect["opcode.other"] = count_opcode_other;
  368. } else {
  369. std::string code_text = Opcode(j).toText();
  370. std::transform(code_text.begin(), code_text.end(),
  371. code_text.begin(), ::tolower);
  372. expect["opcode."+code_text] = j;
  373. }
  374. }
  375. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  376. }
  377. }
  378. TEST_F(CountersTest, incrementRcode) {
  379. Message response(Message::RENDER);
  380. MessageAttributes msgattrs;
  381. std::map<std::string, int> expect;
  382. // Test all rcodes (NOERROR..BADVERS)
  383. int count_all = 0, count_rcode_other = 0, count_ednsbadver = 0;
  384. for (uint16_t i = Rcode::NOERROR().getCode(),
  385. e = Rcode::BADVERS().getCode();
  386. i <= e;
  387. ++i)
  388. {
  389. buildSkeletonMessage(msgattrs);
  390. msgattrs.setRequestOpCode(Opcode::IQUERY());
  391. msgattrs.setRequestSig(false, false);
  392. response.setRcode(Rcode(i));
  393. response.addQuestion(Question(Name("example.com"),
  394. RRClass::IN(), RRType::AAAA()));
  395. response.setHeaderFlag(Message::HEADERFLAG_QR);
  396. for (uint16_t j = 0; j < i; ++j) {
  397. // count up i times for i-th rcode to identify counters
  398. counters.inc(msgattrs, response, true);
  399. ++count_all;
  400. }
  401. expect.clear();
  402. expect["opcode.iquery"] = count_all;
  403. expect["request.v4"] = count_all;
  404. expect["request.udp"] = count_all;
  405. expect["request.edns0"] = count_all;
  406. expect["request.dnssec_ok"] = count_all;
  407. expect["request.tsig"] = 0;
  408. expect["request.sig0"] = 0;
  409. expect["request.badsig"] = 0;
  410. expect["responses"] = count_all;
  411. if (rcode_to_msgcounter[i] == MSG_RCODE_OTHER) {
  412. count_rcode_other += i;
  413. }
  414. // "request.badednsver" counts for Rcode == BADVERS
  415. if (rcode_to_msgcounter[i] == MSG_RCODE_BADVERS) {
  416. count_ednsbadver += i;
  417. }
  418. expect["request.badednsver"] = count_ednsbadver;
  419. for (uint16_t j = 0; j <= i; ++j) {
  420. if (rcode_to_msgcounter[j] == MSG_RCODE_OTHER) {
  421. expect["rcode.other"] = count_rcode_other;
  422. } else {
  423. std::string code_text = Rcode(j).toText();
  424. std::transform(code_text.begin(), code_text.end(),
  425. code_text.begin(), ::tolower);
  426. expect["rcode."+code_text] = j;
  427. }
  428. }
  429. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  430. }
  431. }
  432. TEST_F(CountersTest, incrementTruncated) {
  433. Message response(Message::RENDER);
  434. MessageAttributes msgattrs;
  435. std::map<std::string, int> expect;
  436. // Test these patterns:
  437. // truncated
  438. // -----------
  439. // false
  440. // true
  441. int count_truncated = 0;
  442. for (int i = 0; i < 2; ++i) {
  443. const bool is_truncated = i & 1;
  444. buildSkeletonMessage(msgattrs);
  445. msgattrs.setRequestOpCode(Opcode::IQUERY());
  446. msgattrs.setRequestSig(false, false);
  447. msgattrs.setResponseTruncated(is_truncated);
  448. response.setRcode(Rcode::SERVFAIL());
  449. response.addQuestion(Question(Name("example.com"),
  450. RRClass::IN(), RRType::TXT()));
  451. response.setHeaderFlag(Message::HEADERFLAG_QR);
  452. counters.inc(msgattrs, response, true);
  453. if (is_truncated) {
  454. ++count_truncated;
  455. }
  456. expect.clear();
  457. expect["opcode.iquery"] = i+1;
  458. expect["request.v4"] = i+1;
  459. expect["request.udp"] = i+1;
  460. expect["request.edns0"] = i+1;
  461. expect["request.dnssec_ok"] = i+1;
  462. expect["responses"] = i+1;
  463. expect["rcode.servfail"] = i+1;
  464. expect["response.truncated"] = count_truncated;
  465. checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
  466. }
  467. }
  468. TEST_F(CountersTest, incrementQryAuthAnsAndNoAuthAns) {
  469. Message response(Message::RENDER);
  470. MessageAttributes msgattrs;
  471. std::map<std::string, int> expect;
  472. // Opcode = QUERY, ANCOUNT = 0 (don't care), Rcode = SERVFAIL (don't care)
  473. // Test these patterns:
  474. // AA flag
  475. // -----------------------
  476. // false -> QryNoAuthAns
  477. // true -> QryAuthAns
  478. int count_authans = 0, count_noauthans = 0;
  479. for (int i = 0; i < 2; ++i) {
  480. const bool is_aa_set = i & 1;
  481. buildSkeletonMessage(msgattrs);
  482. msgattrs.setRequestSig(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(MessageAttributes::IP_VERSION_IPV4);
  513. msgattrs.setRequestTransportProtocol(MessageAttributes::TRANSPORT_UDP);
  514. msgattrs.setRequestOpCode(Opcode::QUERY());
  515. msgattrs.setRequestEDNS0(true);
  516. msgattrs.setRequestDO(true);
  517. msgattrs.setRequestSig(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(MessageAttributes::IP_VERSION_IPV4);
  557. msgattrs.setRequestTransportProtocol(MessageAttributes::TRANSPORT_UDP);
  558. msgattrs.setRequestOpCode(Opcode::QUERY());
  559. msgattrs.setRequestEDNS0(true);
  560. msgattrs.setRequestDO(true);
  561. msgattrs.setRequestSig(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(MessageAttributes::IP_VERSION_IPV4);
  595. msgattrs.setRequestTransportProtocol(MessageAttributes::TRANSPORT_UDP);
  596. msgattrs.setRequestOpCode(Opcode::QUERY());
  597. msgattrs.setRequestEDNS0(true);
  598. msgattrs.setRequestDO(true);
  599. msgattrs.setRequestSig(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. }