| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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 | |
| 5 #include "net/quic/quic_received_packet_manager.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "net/quic/quic_connection_stats.h" | |
| 11 #include "net/quic/test_tools/quic_received_packet_manager_peer.h" | |
| 12 #include "testing/gmock/include/gmock/gmock.h" | |
| 13 #include "testing/gtest/include/gtest/gtest.h" | |
| 14 | |
| 15 using std::pair; | |
| 16 using std::vector; | |
| 17 | |
| 18 namespace net { | |
| 19 namespace test { | |
| 20 | |
| 21 class EntropyTrackerPeer { | |
| 22 public: | |
| 23 static QuicPacketSequenceNumber first_gap( | |
| 24 const QuicReceivedPacketManager::EntropyTracker& tracker) { | |
| 25 return tracker.first_gap_; | |
| 26 } | |
| 27 static QuicPacketSequenceNumber largest_observed( | |
| 28 const QuicReceivedPacketManager::EntropyTracker& tracker) { | |
| 29 return tracker.largest_observed_; | |
| 30 } | |
| 31 static int packets_entropy_size( | |
| 32 const QuicReceivedPacketManager::EntropyTracker& tracker) { | |
| 33 return tracker.packets_entropy_.size(); | |
| 34 } | |
| 35 static bool IsTrackingPacket( | |
| 36 const QuicReceivedPacketManager::EntropyTracker& tracker, | |
| 37 QuicPacketSequenceNumber sequence_number) { | |
| 38 return sequence_number >= tracker.first_gap_ && | |
| 39 sequence_number < | |
| 40 (tracker.first_gap_ + tracker.packets_entropy_.size()) && | |
| 41 tracker.packets_entropy_[sequence_number - tracker.first_gap_].second; | |
| 42 } | |
| 43 }; | |
| 44 | |
| 45 namespace { | |
| 46 | |
| 47 // Entropy of individual packets is not tracked if there are no gaps. | |
| 48 TEST(EntropyTrackerTest, NoGaps) { | |
| 49 QuicReceivedPacketManager::EntropyTracker tracker; | |
| 50 | |
| 51 tracker.RecordPacketEntropyHash(1, 23); | |
| 52 tracker.RecordPacketEntropyHash(2, 42); | |
| 53 | |
| 54 EXPECT_EQ(23 ^ 42, tracker.EntropyHash(2)); | |
| 55 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker)); | |
| 56 | |
| 57 EXPECT_EQ(2u, EntropyTrackerPeer::largest_observed(tracker)); | |
| 58 EXPECT_EQ(0, EntropyTrackerPeer::packets_entropy_size(tracker)); | |
| 59 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker, 1)); | |
| 60 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker, 2)); | |
| 61 } | |
| 62 | |
| 63 // Entropy of individual packets is tracked as long as there are gaps. | |
| 64 // Filling the first gap results in entropy getting garbage collected. | |
| 65 TEST(EntropyTrackerTest, FillGaps) { | |
| 66 QuicReceivedPacketManager::EntropyTracker tracker; | |
| 67 | |
| 68 tracker.RecordPacketEntropyHash(2, 5); | |
| 69 tracker.RecordPacketEntropyHash(5, 17); | |
| 70 tracker.RecordPacketEntropyHash(6, 23); | |
| 71 tracker.RecordPacketEntropyHash(9, 42); | |
| 72 | |
| 73 EXPECT_EQ(1u, EntropyTrackerPeer::first_gap(tracker)); | |
| 74 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker)); | |
| 75 EXPECT_EQ(9, EntropyTrackerPeer::packets_entropy_size(tracker)); | |
| 76 | |
| 77 EXPECT_EQ(5, tracker.EntropyHash(2)); | |
| 78 EXPECT_EQ(5 ^ 17, tracker.EntropyHash(5)); | |
| 79 EXPECT_EQ(5 ^ 17 ^ 23, tracker.EntropyHash(6)); | |
| 80 EXPECT_EQ(5 ^ 17 ^ 23 ^ 42, tracker.EntropyHash(9)); | |
| 81 | |
| 82 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker, 1)); | |
| 83 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker, 2)); | |
| 84 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker, 5)); | |
| 85 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker, 6)); | |
| 86 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker, 9)); | |
| 87 | |
| 88 // Fill the gap at 1. | |
| 89 tracker.RecordPacketEntropyHash(1, 2); | |
| 90 | |
| 91 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker)); | |
| 92 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker)); | |
| 93 EXPECT_EQ(7, EntropyTrackerPeer::packets_entropy_size(tracker)); | |
| 94 | |
| 95 EXPECT_EQ(2 ^ 5 ^ 17, tracker.EntropyHash(5)); | |
| 96 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23, tracker.EntropyHash(6)); | |
| 97 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23 ^ 42, tracker.EntropyHash(9)); | |
| 98 | |
| 99 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker, 1)); | |
| 100 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker, 2)); | |
| 101 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker, 5)); | |
| 102 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker, 6)); | |
| 103 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker, 9)); | |
| 104 | |
| 105 // Fill the gap at 4. | |
| 106 tracker.RecordPacketEntropyHash(4, 2); | |
| 107 | |
| 108 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker)); | |
| 109 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker)); | |
| 110 EXPECT_EQ(7, EntropyTrackerPeer::packets_entropy_size(tracker)); | |
| 111 | |
| 112 EXPECT_EQ(5, tracker.EntropyHash(4)); | |
| 113 EXPECT_EQ(5 ^ 17, tracker.EntropyHash(5)); | |
| 114 EXPECT_EQ(5 ^ 17 ^ 23, tracker.EntropyHash(6)); | |
| 115 EXPECT_EQ(5 ^ 17 ^ 23 ^ 42, tracker.EntropyHash(9)); | |
| 116 | |
| 117 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker, 3)); | |
| 118 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker, 4)); | |
| 119 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker, 5)); | |
| 120 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker, 6)); | |
| 121 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker, 9)); | |
| 122 | |
| 123 // Fill the gap at 3. Entropy for packets 3 to 6 are forgotten. | |
| 124 tracker.RecordPacketEntropyHash(3, 2); | |
| 125 | |
| 126 EXPECT_EQ(7u, EntropyTrackerPeer::first_gap(tracker)); | |
| 127 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker)); | |
| 128 EXPECT_EQ(3, EntropyTrackerPeer::packets_entropy_size(tracker)); | |
| 129 | |
| 130 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23 ^ 42, tracker.EntropyHash(9)); | |
| 131 | |
| 132 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker, 3)); | |
| 133 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker, 4)); | |
| 134 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker, 5)); | |
| 135 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker, 6)); | |
| 136 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker, 9)); | |
| 137 | |
| 138 // Fill in the rest. | |
| 139 tracker.RecordPacketEntropyHash(7, 2); | |
| 140 tracker.RecordPacketEntropyHash(8, 2); | |
| 141 | |
| 142 EXPECT_EQ(10u, EntropyTrackerPeer::first_gap(tracker)); | |
| 143 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker)); | |
| 144 EXPECT_EQ(0, EntropyTrackerPeer::packets_entropy_size(tracker)); | |
| 145 | |
| 146 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23 ^ 42, tracker.EntropyHash(9)); | |
| 147 } | |
| 148 | |
| 149 TEST(EntropyTrackerTest, SetCumulativeEntropyUpTo) { | |
| 150 QuicReceivedPacketManager::EntropyTracker tracker; | |
| 151 | |
| 152 tracker.RecordPacketEntropyHash(2, 5); | |
| 153 tracker.RecordPacketEntropyHash(5, 17); | |
| 154 tracker.RecordPacketEntropyHash(6, 23); | |
| 155 tracker.RecordPacketEntropyHash(9, 42); | |
| 156 | |
| 157 EXPECT_EQ(1u, EntropyTrackerPeer::first_gap(tracker)); | |
| 158 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker)); | |
| 159 EXPECT_EQ(9, EntropyTrackerPeer::packets_entropy_size(tracker)); | |
| 160 | |
| 161 // Inform the tracker about value of the hash at a gap. | |
| 162 tracker.SetCumulativeEntropyUpTo(3, 7); | |
| 163 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker)); | |
| 164 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker)); | |
| 165 EXPECT_EQ(7, EntropyTrackerPeer::packets_entropy_size(tracker)); | |
| 166 | |
| 167 EXPECT_EQ(7 ^ 17, tracker.EntropyHash(5)); | |
| 168 EXPECT_EQ(7 ^ 17 ^ 23, tracker.EntropyHash(6)); | |
| 169 EXPECT_EQ(7 ^ 17 ^ 23 ^ 42, tracker.EntropyHash(9)); | |
| 170 | |
| 171 // Inform the tracker about value of the hash at a known location. | |
| 172 tracker.SetCumulativeEntropyUpTo(6, 1); | |
| 173 EXPECT_EQ(7u, EntropyTrackerPeer::first_gap(tracker)); | |
| 174 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker)); | |
| 175 EXPECT_EQ(3, EntropyTrackerPeer::packets_entropy_size(tracker)); | |
| 176 | |
| 177 EXPECT_EQ(1 ^ 23 ^ 42, tracker.EntropyHash(9)); | |
| 178 | |
| 179 // Inform the tracker about value of the hash at the last location. | |
| 180 tracker.SetCumulativeEntropyUpTo(9, 21); | |
| 181 EXPECT_EQ(10u, EntropyTrackerPeer::first_gap(tracker)); | |
| 182 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker)); | |
| 183 EXPECT_EQ(0, EntropyTrackerPeer::packets_entropy_size(tracker)); | |
| 184 | |
| 185 EXPECT_EQ(42 ^ 21, tracker.EntropyHash(9)); | |
| 186 } | |
| 187 | |
| 188 class QuicReceivedPacketManagerTest : public ::testing::Test { | |
| 189 protected: | |
| 190 QuicReceivedPacketManagerTest() : received_manager_(&stats_) {} | |
| 191 | |
| 192 void RecordPacketReceipt(QuicPacketSequenceNumber sequence_number, | |
| 193 QuicPacketEntropyHash entropy_hash) { | |
| 194 RecordPacketReceipt(sequence_number, entropy_hash, QuicTime::Zero()); | |
| 195 } | |
| 196 | |
| 197 void RecordPacketReceipt(QuicPacketSequenceNumber sequence_number, | |
| 198 QuicPacketEntropyHash entropy_hash, | |
| 199 QuicTime receipt_time) { | |
| 200 QuicPacketHeader header; | |
| 201 header.packet_sequence_number = sequence_number; | |
| 202 header.entropy_hash = entropy_hash; | |
| 203 received_manager_.RecordPacketReceived(0u, header, receipt_time); | |
| 204 } | |
| 205 | |
| 206 void RecordPacketRevived(QuicPacketSequenceNumber sequence_number) { | |
| 207 received_manager_.RecordPacketRevived(sequence_number); | |
| 208 } | |
| 209 | |
| 210 QuicConnectionStats stats_; | |
| 211 QuicReceivedPacketManager received_manager_; | |
| 212 }; | |
| 213 | |
| 214 TEST_F(QuicReceivedPacketManagerTest, ReceivedPacketEntropyHash) { | |
| 215 vector<pair<QuicPacketSequenceNumber, QuicPacketEntropyHash> > entropies; | |
| 216 entropies.push_back(std::make_pair(1, 12)); | |
| 217 entropies.push_back(std::make_pair(7, 1)); | |
| 218 entropies.push_back(std::make_pair(2, 33)); | |
| 219 entropies.push_back(std::make_pair(5, 3)); | |
| 220 entropies.push_back(std::make_pair(8, 34)); | |
| 221 | |
| 222 for (size_t i = 0; i < entropies.size(); ++i) { | |
| 223 RecordPacketReceipt(entropies[i].first, entropies[i].second); | |
| 224 } | |
| 225 | |
| 226 std::sort(entropies.begin(), entropies.end()); | |
| 227 | |
| 228 QuicPacketEntropyHash hash = 0; | |
| 229 size_t index = 0; | |
| 230 for (size_t i = 1; i <= (*entropies.rbegin()).first; ++i) { | |
| 231 if (entropies[index].first == i) { | |
| 232 hash ^= entropies[index].second; | |
| 233 ++index; | |
| 234 } | |
| 235 if (i < 3) continue; | |
| 236 EXPECT_EQ(hash, received_manager_.EntropyHash(i)); | |
| 237 } | |
| 238 // Reorder by 5 when 2 is received after 7. | |
| 239 EXPECT_EQ(5u, stats_.max_sequence_reordering); | |
| 240 EXPECT_EQ(0, stats_.max_time_reordering_us); | |
| 241 EXPECT_EQ(2u, stats_.packets_reordered); | |
| 242 } | |
| 243 | |
| 244 TEST_F(QuicReceivedPacketManagerTest, EntropyHashBelowLeastObserved) { | |
| 245 EXPECT_EQ(0, received_manager_.EntropyHash(0)); | |
| 246 RecordPacketReceipt(4, 5); | |
| 247 EXPECT_EQ(0, received_manager_.EntropyHash(3)); | |
| 248 } | |
| 249 | |
| 250 TEST_F(QuicReceivedPacketManagerTest, EntropyHashAboveLargestObserved) { | |
| 251 EXPECT_EQ(0, received_manager_.EntropyHash(0)); | |
| 252 RecordPacketReceipt(4, 5); | |
| 253 EXPECT_EQ(0, received_manager_.EntropyHash(3)); | |
| 254 } | |
| 255 | |
| 256 TEST_F(QuicReceivedPacketManagerTest, SetCumulativeEntropyUpTo) { | |
| 257 vector<pair<QuicPacketSequenceNumber, QuicPacketEntropyHash> > entropies; | |
| 258 entropies.push_back(std::make_pair(1, 12)); | |
| 259 entropies.push_back(std::make_pair(2, 1)); | |
| 260 entropies.push_back(std::make_pair(3, 33)); | |
| 261 entropies.push_back(std::make_pair(4, 3)); | |
| 262 entropies.push_back(std::make_pair(6, 34)); | |
| 263 entropies.push_back(std::make_pair(7, 29)); | |
| 264 | |
| 265 QuicPacketEntropyHash entropy_hash = 0; | |
| 266 for (size_t i = 0; i < entropies.size(); ++i) { | |
| 267 RecordPacketReceipt(entropies[i].first, entropies[i].second); | |
| 268 entropy_hash ^= entropies[i].second; | |
| 269 } | |
| 270 EXPECT_EQ(entropy_hash, received_manager_.EntropyHash(7)); | |
| 271 | |
| 272 // Now set the entropy hash up to 5 to be 100. | |
| 273 entropy_hash ^= 100; | |
| 274 for (size_t i = 0; i < 4; ++i) { | |
| 275 entropy_hash ^= entropies[i].second; | |
| 276 } | |
| 277 QuicReceivedPacketManagerPeer::SetCumulativeEntropyUpTo( | |
| 278 &received_manager_, 5, 100); | |
| 279 EXPECT_EQ(entropy_hash, received_manager_.EntropyHash(7)); | |
| 280 | |
| 281 QuicReceivedPacketManagerPeer::SetCumulativeEntropyUpTo( | |
| 282 &received_manager_, 1, 50); | |
| 283 EXPECT_EQ(entropy_hash, received_manager_.EntropyHash(7)); | |
| 284 | |
| 285 // No reordering. | |
| 286 EXPECT_EQ(0u, stats_.max_sequence_reordering); | |
| 287 EXPECT_EQ(0, stats_.max_time_reordering_us); | |
| 288 EXPECT_EQ(0u, stats_.packets_reordered); | |
| 289 } | |
| 290 | |
| 291 TEST_F(QuicReceivedPacketManagerTest, DontWaitForPacketsBefore) { | |
| 292 QuicPacketHeader header; | |
| 293 header.packet_sequence_number = 2u; | |
| 294 received_manager_.RecordPacketReceived(0u, header, QuicTime::Zero()); | |
| 295 header.packet_sequence_number = 7u; | |
| 296 received_manager_.RecordPacketReceived(0u, header, QuicTime::Zero()); | |
| 297 EXPECT_TRUE(received_manager_.IsAwaitingPacket(3u)); | |
| 298 EXPECT_TRUE(received_manager_.IsAwaitingPacket(6u)); | |
| 299 EXPECT_TRUE(QuicReceivedPacketManagerPeer::DontWaitForPacketsBefore( | |
| 300 &received_manager_, 4)); | |
| 301 EXPECT_FALSE(received_manager_.IsAwaitingPacket(3u)); | |
| 302 EXPECT_TRUE(received_manager_.IsAwaitingPacket(6u)); | |
| 303 } | |
| 304 | |
| 305 TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedPacketInfo) { | |
| 306 QuicPacketHeader header; | |
| 307 header.packet_sequence_number = 2u; | |
| 308 QuicTime two_ms = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(2)); | |
| 309 received_manager_.RecordPacketReceived(0u, header, two_ms); | |
| 310 | |
| 311 QuicAckFrame ack; | |
| 312 received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero()); | |
| 313 // When UpdateReceivedPacketInfo with a time earlier than the time of the | |
| 314 // largest observed packet, make sure that the delta is 0, not negative. | |
| 315 EXPECT_EQ(QuicTime::Delta::Zero(), ack.delta_time_largest_observed); | |
| 316 EXPECT_FALSE(ack.received_packet_times.empty()); | |
| 317 | |
| 318 QuicTime four_ms = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(4)); | |
| 319 received_manager_.UpdateReceivedPacketInfo(&ack, four_ms); | |
| 320 // When UpdateReceivedPacketInfo after not having received a new packet, | |
| 321 // the delta should still be accurate. | |
| 322 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2), | |
| 323 ack.delta_time_largest_observed); | |
| 324 } | |
| 325 | |
| 326 TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedConnectionStats) { | |
| 327 RecordPacketReceipt(1, 0); | |
| 328 RecordPacketReceipt(6, 0); | |
| 329 RecordPacketReceipt( | |
| 330 2, 0, QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(1))); | |
| 331 | |
| 332 EXPECT_EQ(4u, stats_.max_sequence_reordering); | |
| 333 EXPECT_EQ(1000, stats_.max_time_reordering_us); | |
| 334 EXPECT_EQ(1u, stats_.packets_reordered); | |
| 335 } | |
| 336 | |
| 337 TEST_F(QuicReceivedPacketManagerTest, RevivedPacket) { | |
| 338 RecordPacketReceipt(1, 0); | |
| 339 RecordPacketReceipt(3, 0); | |
| 340 RecordPacketRevived(2); | |
| 341 | |
| 342 QuicAckFrame ack; | |
| 343 received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero()); | |
| 344 EXPECT_EQ(1u, ack.missing_packets.size()); | |
| 345 EXPECT_EQ(2u, *ack.missing_packets.begin()); | |
| 346 EXPECT_EQ(1u, ack.revived_packets.size()); | |
| 347 EXPECT_EQ(2u, *ack.missing_packets.begin()); | |
| 348 } | |
| 349 | |
| 350 TEST_F(QuicReceivedPacketManagerTest, PacketRevivedThenReceived) { | |
| 351 RecordPacketReceipt(1, 0); | |
| 352 RecordPacketReceipt(3, 0); | |
| 353 RecordPacketRevived(2); | |
| 354 RecordPacketReceipt(2, 0); | |
| 355 | |
| 356 QuicAckFrame ack; | |
| 357 received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero()); | |
| 358 EXPECT_TRUE(ack.missing_packets.empty()); | |
| 359 EXPECT_TRUE(ack.revived_packets.empty()); | |
| 360 } | |
| 361 | |
| 362 | |
| 363 } // namespace | |
| 364 } // namespace test | |
| 365 } // namespace net | |
| OLD | NEW |