| Index: net/quic/quic_sent_entropy_manager.cc
|
| diff --git a/net/quic/quic_sent_entropy_manager.cc b/net/quic/quic_sent_entropy_manager.cc
|
| index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b74229946233d92be6fbd9615fe02cccc14d197d 100644
|
| --- a/net/quic/quic_sent_entropy_manager.cc
|
| +++ b/net/quic/quic_sent_entropy_manager.cc
|
| @@ -0,0 +1,87 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "net/quic/quic_sent_entropy_manager.h"
|
| +
|
| +#include "base/logging.h"
|
| +#include "net/base/linked_hash_map.h"
|
| +
|
| +using std::make_pair;
|
| +using std::max;
|
| +using std::min;
|
| +
|
| +namespace net {
|
| +
|
| +QuicSentEntropyManager::QuicSentEntropyManager()
|
| + : packets_entropy_hash_(0) {}
|
| +
|
| +QuicSentEntropyManager::~QuicSentEntropyManager() {}
|
| +
|
| +void QuicSentEntropyManager::RecordPacketEntropyHash(
|
| + QuicPacketSequenceNumber sequence_number,
|
| + QuicPacketEntropyHash entropy_hash) {
|
| + // TODO(satyamshekhar): Check this logic again when/if we enable packet
|
| + // reordering.
|
| + packets_entropy_hash_ ^= entropy_hash;
|
| + packets_entropy_.insert(
|
| + make_pair(sequence_number,
|
| + make_pair(entropy_hash, packets_entropy_hash_)));
|
| + DVLOG(2) << "setting cumulative sent entropy hash to: "
|
| + << static_cast<int>(packets_entropy_hash_)
|
| + << " updated with sequence number " << sequence_number
|
| + << " entropy hash: " << static_cast<int>(entropy_hash);
|
| +}
|
| +
|
| +QuicPacketEntropyHash QuicSentEntropyManager::EntropyHash(
|
| + QuicPacketSequenceNumber sequence_number) const {
|
| + SentEntropyMap::const_iterator it =
|
| + packets_entropy_.find(sequence_number);
|
| + if (it == packets_entropy_.end()) {
|
| + // Should only happen when we have not received ack for any packet.
|
| + DCHECK_EQ(0u, sequence_number);
|
| + return 0;
|
| + }
|
| + return it->second.second;
|
| +}
|
| +
|
| +bool QuicSentEntropyManager::IsValidEntropy(
|
| + QuicPacketSequenceNumber sequence_number,
|
| + const SequenceNumberSet& missing_packets,
|
| + QuicPacketEntropyHash entropy_hash) const {
|
| + SentEntropyMap::const_iterator entropy_it =
|
| + packets_entropy_.find(sequence_number);
|
| + if (entropy_it == packets_entropy_.end()) {
|
| + DCHECK_EQ(0u, sequence_number);
|
| + // Close connection if something goes wrong.
|
| + return 0 == sequence_number;
|
| + }
|
| + QuicPacketEntropyHash expected_entropy_hash = entropy_it->second.second;
|
| + for (SequenceNumberSet::const_iterator it = missing_packets.begin();
|
| + it != missing_packets.end(); ++it) {
|
| + entropy_it = packets_entropy_.find(*it);
|
| + DCHECK(entropy_it != packets_entropy_.end());
|
| + expected_entropy_hash ^= entropy_it->second.first;
|
| + }
|
| + DLOG_IF(WARNING, entropy_hash != expected_entropy_hash)
|
| + << "Invalid entropy hash: " << static_cast<int>(entropy_hash)
|
| + << " expected entropy hash: " << static_cast<int>(expected_entropy_hash);
|
| + return entropy_hash == expected_entropy_hash;
|
| +}
|
| +
|
| +void QuicSentEntropyManager::ClearEntropyBefore(
|
| + QuicPacketSequenceNumber sequence_number) {
|
| + if (packets_entropy_.empty()) {
|
| + return;
|
| + }
|
| + SentEntropyMap::iterator it = packets_entropy_.begin();
|
| + while (it->first < sequence_number) {
|
| + packets_entropy_.erase(it);
|
| + it = packets_entropy_.begin();
|
| + DCHECK(it != packets_entropy_.end());
|
| + }
|
| + DVLOG(2) << "Cleared entropy before: "
|
| + << packets_entropy_.begin()->first;
|
| +}
|
| +
|
| +} // namespace net
|
|
|