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.
5 #include "net/quic/quic_sent_entropy_manager.h"
7 #include "base/logging.h"
8 #include "net/base/linked_hash_map.h"
16 QuicSentEntropyManager::QuicSentEntropyManager()
17 : packets_entropy_hash_(0) {}
19 QuicSentEntropyManager::~QuicSentEntropyManager() {}
21 void QuicSentEntropyManager::RecordPacketEntropyHash(
22 QuicPacketSequenceNumber sequence_number
,
23 QuicPacketEntropyHash entropy_hash
) {
24 // TODO(satyamshekhar): Check this logic again when/if we enable packet
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
);
36 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
);
45 return it
->second
.second
;
48 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
;
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
;
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
;
72 void QuicSentEntropyManager::ClearEntropyBefore(
73 QuicPacketSequenceNumber sequence_number
) {
74 if (packets_entropy_
.empty()) {
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());
83 DVLOG(2) << "Cleared entropy before: "
84 << packets_entropy_
.begin()->first
;