| Index: net/quic/quic_potential_connection_store.cc
|
| diff --git a/net/quic/quic_potential_connection_store.cc b/net/quic/quic_potential_connection_store.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e9c49cf812b77bf1d2a2675d8c9bd202050eca2f
|
| --- /dev/null
|
| +++ b/net/quic/quic_potential_connection_store.cc
|
| @@ -0,0 +1,130 @@
|
| +#include "net/quic/quic_potential_connection_store.h"
|
| +
|
| +#include <list>
|
| +
|
| +#include "base/stl_util.h"
|
| +
|
| +namespace net {
|
| +
|
| +typedef QuicPotentialConnectionStore::BufferedPacket BufferedPacket;
|
| +typedef QuicPotentialConnectionStore::EnqueuePacketResult EnqueuePacketResult;
|
| +
|
| +// Max number of connections this store can keep track.
|
| +static const size_t kDefaultMaxConnectionsInStore = 100;
|
| +
|
| +namespace {
|
| +
|
| +// This alarm removes expired entries in map each time this alarm fires.
|
| +class NET_EXPORT_PRIVATE ConnectionExpireAlarm : public QuicAlarm::Delegate {
|
| + public:
|
| + explicit ConnectionExpireAlarm(QuicPotentialConnectionStore* store)
|
| + : connection_store_(store) {}
|
| +
|
| + void OnAlarm() override { connection_store_->OnExpirationTimeout(); }
|
| +
|
| + // Disallow copy and asign.
|
| + ConnectionExpireAlarm(const ConnectionExpireAlarm&) = delete;
|
| + ConnectionExpireAlarm& operator=(const ConnectionExpireAlarm&) = delete;
|
| +
|
| + private:
|
| + QuicPotentialConnectionStore* connection_store_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +QuicPotentialConnectionStore::BufferedPacket::BufferedPacket(
|
| + std::unique_ptr<QuicEncryptedPacket> packet,
|
| + IPEndPoint server_address,
|
| + IPEndPoint client_address)
|
| + : packet(std::move(packet)),
|
| + server_address(server_address),
|
| + client_address(client_address) {}
|
| +
|
| +QuicPotentialConnectionStore::BufferedPacket::BufferedPacket(
|
| + BufferedPacket&& other) {
|
| + packet = std::move(other.packet);
|
| + server_address = other.server_address;
|
| + client_address = other.client_address;
|
| +}
|
| +
|
| +QuicPotentialConnectionStore::BufferedPacket::~BufferedPacket() {}
|
| +
|
| +QuicPotentialConnectionStore::BufferedPacketList::BufferedPacketList()
|
| + : creation_time(QuicTime::Zero()) {}
|
| +
|
| +QuicPotentialConnectionStore::BufferedPacketList::~BufferedPacketList() {}
|
| +
|
| +QuicPotentialConnectionStore::QuicPotentialConnectionStore(
|
| + VisitorInterface* visitor,
|
| + QuicClock* clock,
|
| + QuicAlarmFactory* alarm_factory)
|
| + : connection_life_span_(
|
| + QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs)),
|
| + visitor_(visitor),
|
| + clock_(clock),
|
| + expiration_alarm_(
|
| + alarm_factory->CreateAlarm(new ConnectionExpireAlarm(this))) {}
|
| +
|
| +QuicPotentialConnectionStore::~QuicPotentialConnectionStore() {}
|
| +
|
| +EnqueuePacketResult QuicPotentialConnectionStore::EnqueuePacket(
|
| + QuicConnectionId connection_id,
|
| + const QuicEncryptedPacket& packet,
|
| + IPEndPoint server_address,
|
| + IPEndPoint client_address) {
|
| + if (!ContainsKey(undecryptable_packets_, connection_id) &&
|
| + undecryptable_packets_.size() >= kDefaultMaxConnectionsInStore) {
|
| + // Drop the packet if store can't keep track of more connections.
|
| + return TOO_MANY_CONNECTIONS;
|
| + }
|
| + BufferedPacketList& queue =
|
| + undecryptable_packets_.find(connection_id)->second;
|
| +
|
| + if (queue.buffered_packets.size() >= kDefaultMaxUndecryptablePackets) {
|
| + // If there are kMaxBufferedPacketsPerConnection packets buffered up for
|
| + // this connection, drop the current packet.
|
| + return TOO_MANY_PACKETS;
|
| + }
|
| +
|
| + if (queue.buffered_packets.empty()) {
|
| + // If this is the first packet arrived on a new connection, initialize the
|
| + // creation time.
|
| + queue.creation_time = clock_->ApproximateNow();
|
| + }
|
| +
|
| + BufferedPacket new_entry(std::unique_ptr<QuicEncryptedPacket>(packet.Clone()),
|
| + server_address, client_address);
|
| +
|
| + queue.buffered_packets.push_back(std::move(new_entry));
|
| +
|
| + if (!expiration_alarm_->IsSet()) {
|
| + expiration_alarm_->Set(clock_->ApproximateNow().Add(connection_life_span_));
|
| + }
|
| + return SUCCESS;
|
| +}
|
| +
|
| +std::list<BufferedPacket> QuicPotentialConnectionStore::DeliverPackets(
|
| + QuicConnectionId connection_id) {
|
| + std::list<BufferedPacket> packets_to_deliver = std::move(
|
| + undecryptable_packets_.find(connection_id)->second.buffered_packets);
|
| + undecryptable_packets_.erase(connection_id);
|
| + return packets_to_deliver;
|
| +}
|
| +
|
| +void QuicPotentialConnectionStore::OnExpirationTimeout() {
|
| + QuicTime expiration_time =
|
| + clock_->ApproximateNow().Subtract(connection_life_span_);
|
| + while (!undecryptable_packets_.empty()) {
|
| + auto& entry = undecryptable_packets_.front();
|
| + if (entry.second.creation_time > expiration_time) {
|
| + break;
|
| + }
|
| + visitor_->OnExpiredPackets(entry.first, std::move(entry.second));
|
| + undecryptable_packets_.erase(undecryptable_packets_.begin());
|
| + }
|
| + if (!undecryptable_packets_.empty()) {
|
| + expiration_alarm_->Set(clock_->ApproximateNow().Add(connection_life_span_));
|
| + }
|
| +}
|
| +
|
| +} // namespace net
|
|
|