dns_udp_tracker_unittest.cc 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/dns/dns_udp_tracker.h"
  5. #include "base/test/simple_test_tick_clock.h"
  6. #include "net/base/net_errors.h"
  7. #include "testing/gtest/include/gtest/gtest.h"
  8. namespace net {
  9. namespace {
  10. class DnsUdpTrackerTest : public testing::Test {
  11. public:
  12. DnsUdpTrackerTest() {
  13. tracker_.set_tick_clock_for_testing(&test_tick_clock_);
  14. }
  15. protected:
  16. DnsUdpTracker tracker_;
  17. base::SimpleTestTickClock test_tick_clock_;
  18. };
  19. TEST_F(DnsUdpTrackerTest, MatchingId) {
  20. uint16_t port = 416;
  21. uint16_t id = 56;
  22. for (size_t i = 0; i < DnsUdpTracker::kRecognizedIdMismatchThreshold; ++i) {
  23. tracker_.RecordQuery(++port, ++id);
  24. tracker_.RecordResponseId(id /* query_id */, id /* response_id */);
  25. EXPECT_FALSE(tracker_.low_entropy());
  26. }
  27. }
  28. TEST_F(DnsUdpTrackerTest, ReusedMismatches) {
  29. static const uint16_t kOldId = 786;
  30. tracker_.RecordQuery(123 /* port */, kOldId);
  31. uint16_t port = 3889;
  32. uint16_t id = 3456;
  33. for (size_t i = 0; i < DnsUdpTracker::kRecognizedIdMismatchThreshold; ++i) {
  34. EXPECT_FALSE(tracker_.low_entropy());
  35. tracker_.RecordQuery(++port, ++id);
  36. tracker_.RecordResponseId(id /* query_id */, kOldId /* response_id */);
  37. }
  38. EXPECT_TRUE(tracker_.low_entropy());
  39. }
  40. TEST_F(DnsUdpTrackerTest, ReusedMismatches_Expired) {
  41. static const uint16_t kOldId = 786;
  42. tracker_.RecordQuery(123 /* port */, kOldId);
  43. test_tick_clock_.Advance(DnsUdpTracker::kMaxAge + base::Milliseconds(1));
  44. uint16_t port = 3889;
  45. uint16_t id = 3456;
  46. // Because the query record has expired, the ID should be treated as
  47. // unrecognized.
  48. for (size_t i = 0; i < DnsUdpTracker::kUnrecognizedIdMismatchThreshold; ++i) {
  49. EXPECT_FALSE(tracker_.low_entropy());
  50. tracker_.RecordQuery(++port, ++id);
  51. tracker_.RecordResponseId(id /* query_id */, kOldId /* response_id */);
  52. }
  53. EXPECT_TRUE(tracker_.low_entropy());
  54. }
  55. // Test for ID mismatches using an ID still kept in recorded queries, but not
  56. // recent enough to be considered reognized.
  57. TEST_F(DnsUdpTrackerTest, ReusedMismatches_Old) {
  58. static const uint16_t kOldId = 786;
  59. tracker_.RecordQuery(123 /* port */, kOldId);
  60. test_tick_clock_.Advance(DnsUdpTracker::kMaxRecognizedIdAge +
  61. base::Milliseconds(1));
  62. uint16_t port = 3889;
  63. uint16_t id = 3456;
  64. // Expect the ID to be treated as unrecognized.
  65. for (size_t i = 0; i < DnsUdpTracker::kUnrecognizedIdMismatchThreshold; ++i) {
  66. EXPECT_FALSE(tracker_.low_entropy());
  67. tracker_.RecordQuery(++port, ++id);
  68. tracker_.RecordResponseId(id /* query_id */, kOldId /* response_id */);
  69. }
  70. EXPECT_TRUE(tracker_.low_entropy());
  71. }
  72. TEST_F(DnsUdpTrackerTest, ReusedMismatches_Full) {
  73. static const uint16_t kOldId = 786;
  74. tracker_.RecordQuery(123 /* port */, kOldId);
  75. uint16_t port = 124;
  76. uint16_t id = 3457;
  77. for (size_t i = 0; i < DnsUdpTracker::kMaxRecordedQueries; ++i) {
  78. tracker_.RecordQuery(++port, ++id);
  79. }
  80. // Expect the ID to be treated as unrecognized.
  81. for (size_t i = 0; i < DnsUdpTracker::kUnrecognizedIdMismatchThreshold; ++i) {
  82. EXPECT_FALSE(tracker_.low_entropy());
  83. tracker_.RecordResponseId(id /* query_id */, kOldId /* response_id */);
  84. }
  85. EXPECT_TRUE(tracker_.low_entropy());
  86. }
  87. TEST_F(DnsUdpTrackerTest, UnknownMismatches) {
  88. uint16_t port = 10014;
  89. uint16_t id = 4332;
  90. for (size_t i = 0; i < DnsUdpTracker::kUnrecognizedIdMismatchThreshold; ++i) {
  91. EXPECT_FALSE(tracker_.low_entropy());
  92. tracker_.RecordQuery(++port, ++id);
  93. tracker_.RecordResponseId(id /* query_id */, 743 /* response_id */);
  94. }
  95. EXPECT_TRUE(tracker_.low_entropy());
  96. }
  97. TEST_F(DnsUdpTrackerTest, ReusedPort) {
  98. static const uint16_t kPort = 2135;
  99. tracker_.RecordQuery(kPort, 579 /* query_id */);
  100. uint16_t id = 580;
  101. for (int i = 0; i < DnsUdpTracker::kPortReuseThreshold; ++i) {
  102. EXPECT_FALSE(tracker_.low_entropy());
  103. tracker_.RecordQuery(kPort, ++id);
  104. tracker_.RecordResponseId(id /* query_id */, id /* response_id */);
  105. }
  106. EXPECT_TRUE(tracker_.low_entropy());
  107. }
  108. TEST_F(DnsUdpTrackerTest, ReusedPort_Expired) {
  109. static const uint16_t kPort = 2135;
  110. tracker_.RecordQuery(kPort, 579 /* query_id */);
  111. test_tick_clock_.Advance(DnsUdpTracker::kMaxAge + base::Milliseconds(1));
  112. EXPECT_FALSE(tracker_.low_entropy());
  113. uint16_t id = 580;
  114. for (int i = 0; i < DnsUdpTracker::kPortReuseThreshold; ++i) {
  115. tracker_.RecordQuery(kPort, ++id);
  116. tracker_.RecordResponseId(id /* query_id */, id /* response_id */);
  117. EXPECT_FALSE(tracker_.low_entropy());
  118. }
  119. }
  120. TEST_F(DnsUdpTrackerTest, ReusedPort_Full) {
  121. static const uint16_t kPort = 2135;
  122. tracker_.RecordQuery(kPort, 579 /* query_id */);
  123. uint16_t port = 124;
  124. uint16_t id = 3457;
  125. for (size_t i = 0; i < DnsUdpTracker::kMaxRecordedQueries; ++i) {
  126. tracker_.RecordQuery(++port, ++id);
  127. }
  128. EXPECT_FALSE(tracker_.low_entropy());
  129. for (int i = 0; i < DnsUdpTracker::kPortReuseThreshold; ++i) {
  130. tracker_.RecordQuery(kPort, ++id);
  131. tracker_.RecordResponseId(id /* query_id */, id /* response_id */);
  132. EXPECT_FALSE(tracker_.low_entropy());
  133. }
  134. }
  135. TEST_F(DnsUdpTrackerTest, ConnectionError) {
  136. tracker_.RecordConnectionError(ERR_FAILED);
  137. EXPECT_FALSE(tracker_.low_entropy());
  138. }
  139. TEST_F(DnsUdpTrackerTest, ConnectionError_InsufficientResources) {
  140. tracker_.RecordConnectionError(ERR_INSUFFICIENT_RESOURCES);
  141. EXPECT_TRUE(tracker_.low_entropy());
  142. }
  143. } // namespace
  144. } // namespace net