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