• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_sent_entropy_manager.h"
6 
7 #include "base/logging.h"
8 #include "net/base/linked_hash_map.h"
9 
10 using std::make_pair;
11 using std::max;
12 using std::min;
13 
14 namespace net {
15 
QuicSentEntropyManager()16 QuicSentEntropyManager::QuicSentEntropyManager()
17     : packets_entropy_hash_(0) {}
18 
~QuicSentEntropyManager()19 QuicSentEntropyManager::~QuicSentEntropyManager() {}
20 
RecordPacketEntropyHash(QuicPacketSequenceNumber sequence_number,QuicPacketEntropyHash entropy_hash)21 void QuicSentEntropyManager::RecordPacketEntropyHash(
22     QuicPacketSequenceNumber sequence_number,
23     QuicPacketEntropyHash entropy_hash) {
24   // TODO(satyamshekhar): Check this logic again when/if we enable packet
25   // reordering.
26   packets_entropy_hash_ ^= entropy_hash;
27   packets_entropy_.insert(
28       make_pair(sequence_number,
29                 make_pair(entropy_hash, packets_entropy_hash_)));
30   DVLOG(2) << "setting cumulative sent entropy hash to: "
31            << static_cast<int>(packets_entropy_hash_)
32            << " updated with sequence number " << sequence_number
33            << " entropy hash: " << static_cast<int>(entropy_hash);
34 }
35 
EntropyHash(QuicPacketSequenceNumber sequence_number) const36 QuicPacketEntropyHash QuicSentEntropyManager::EntropyHash(
37     QuicPacketSequenceNumber sequence_number) const {
38   SentEntropyMap::const_iterator it =
39       packets_entropy_.find(sequence_number);
40   if (it == packets_entropy_.end()) {
41     // Should only happen when we have not received ack for any packet.
42     DCHECK_EQ(0u, sequence_number);
43     return 0;
44   }
45   return it->second.second;
46 }
47 
IsValidEntropy(QuicPacketSequenceNumber sequence_number,const SequenceNumberSet & missing_packets,QuicPacketEntropyHash entropy_hash) const48 bool QuicSentEntropyManager::IsValidEntropy(
49     QuicPacketSequenceNumber sequence_number,
50     const SequenceNumberSet& missing_packets,
51     QuicPacketEntropyHash entropy_hash) const {
52   SentEntropyMap::const_iterator entropy_it =
53       packets_entropy_.find(sequence_number);
54   if (entropy_it == packets_entropy_.end()) {
55     DCHECK_EQ(0u, sequence_number);
56     // Close connection if something goes wrong.
57     return 0 == sequence_number;
58   }
59   QuicPacketEntropyHash expected_entropy_hash = entropy_it->second.second;
60   for (SequenceNumberSet::const_iterator it = missing_packets.begin();
61        it != missing_packets.end(); ++it) {
62     entropy_it = packets_entropy_.find(*it);
63     DCHECK(entropy_it != packets_entropy_.end());
64     expected_entropy_hash ^= entropy_it->second.first;
65   }
66   DLOG_IF(WARNING, entropy_hash != expected_entropy_hash)
67       << "Invalid entropy hash: " << static_cast<int>(entropy_hash)
68       << " expected entropy hash: " << static_cast<int>(expected_entropy_hash);
69   return entropy_hash == expected_entropy_hash;
70 }
71 
ClearEntropyBefore(QuicPacketSequenceNumber sequence_number)72 void QuicSentEntropyManager::ClearEntropyBefore(
73     QuicPacketSequenceNumber sequence_number) {
74   if (packets_entropy_.empty()) {
75     return;
76   }
77   SentEntropyMap::iterator it = packets_entropy_.begin();
78   while (it->first < sequence_number) {
79     packets_entropy_.erase(it);
80     it = packets_entropy_.begin();
81     DCHECK(it != packets_entropy_.end());
82   }
83   DVLOG(2) << "Cleared entropy before: "
84            << packets_entropy_.begin()->first;
85 }
86 
87 }  // namespace net
88