OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2016 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_buffered_packet_store.h" | |
6 | |
7 #include <list> | |
8 | |
9 #include "base/stl_util.h" | |
10 | |
11 namespace net { | |
12 | |
13 typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket; | |
14 typedef QuicBufferedPacketStore::EnqueuePacketResult EnqueuePacketResult; | |
15 typedef QuicBufferedPacketStore::BufferedPacketList BufferedPacketList; | |
16 | |
17 // Max number of connections this store can keep track. | |
18 static const size_t kDefaultMaxConnectionsInStore = 100; | |
19 | |
20 namespace { | |
21 | |
22 // This alarm removes expired entries in map each time this alarm fires. | |
23 class NET_EXPORT_PRIVATE ConnectionExpireAlarm : public QuicAlarm::Delegate { | |
Ryan Hamilton
2016/05/27 15:47:51
From the windows error message, I think you don't
| |
24 public: | |
25 explicit ConnectionExpireAlarm(QuicBufferedPacketStore* store) | |
26 : connection_store_(store) {} | |
27 | |
28 void OnAlarm() override { connection_store_->OnExpirationTimeout(); } | |
29 | |
30 // Disallow copy and asign. | |
31 ConnectionExpireAlarm(const ConnectionExpireAlarm&) = delete; | |
32 ConnectionExpireAlarm& operator=(const ConnectionExpireAlarm&) = delete; | |
33 | |
34 private: | |
35 QuicBufferedPacketStore* connection_store_; | |
36 }; | |
37 | |
38 } // namespace | |
39 | |
40 BufferedPacket::BufferedPacket(std::unique_ptr<QuicEncryptedPacket> packet, | |
41 IPEndPoint server_address, | |
42 IPEndPoint client_address) | |
43 : packet(std::move(packet)), | |
44 server_address(server_address), | |
45 client_address(client_address) {} | |
46 | |
47 BufferedPacket::BufferedPacket(BufferedPacket&& other) = default; | |
48 | |
49 BufferedPacket& BufferedPacket::operator=(BufferedPacket&& other) = default; | |
50 | |
51 BufferedPacket::~BufferedPacket() {} | |
52 | |
53 BufferedPacketList::BufferedPacketList() : creation_time(QuicTime::Zero()) {} | |
54 | |
55 BufferedPacketList::BufferedPacketList(BufferedPacketList&& other) = default; | |
56 | |
57 BufferedPacketList& BufferedPacketList::operator=(BufferedPacketList&& other) = | |
58 default; | |
59 | |
60 BufferedPacketList::~BufferedPacketList() {} | |
61 | |
62 QuicBufferedPacketStore::QuicBufferedPacketStore( | |
63 VisitorInterface* visitor, | |
64 QuicClock* clock, | |
65 QuicAlarmFactory* alarm_factory) | |
66 : connection_life_span_( | |
67 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs)), | |
68 visitor_(visitor), | |
69 clock_(clock), | |
70 expiration_alarm_( | |
71 alarm_factory->CreateAlarm(new ConnectionExpireAlarm(this))) {} | |
72 | |
73 QuicBufferedPacketStore::~QuicBufferedPacketStore() {} | |
74 | |
75 EnqueuePacketResult QuicBufferedPacketStore::EnqueuePacket( | |
76 QuicConnectionId connection_id, | |
77 const QuicEncryptedPacket& packet, | |
78 IPEndPoint server_address, | |
79 IPEndPoint client_address) { | |
80 if (!ContainsKey(undecryptable_packets_, connection_id) && | |
81 undecryptable_packets_.size() >= kDefaultMaxConnectionsInStore) { | |
82 // Drop the packet if store can't keep track of more connections. | |
83 return TOO_MANY_CONNECTIONS; | |
84 } else if (!ContainsKey(undecryptable_packets_, connection_id)) { | |
85 undecryptable_packets_.emplace( | |
86 std::make_pair(connection_id, BufferedPacketList())); | |
87 } | |
88 CHECK(ContainsKey(undecryptable_packets_, connection_id)); | |
89 BufferedPacketList& queue = | |
90 undecryptable_packets_.find(connection_id)->second; | |
91 | |
92 if (queue.buffered_packets.size() >= kDefaultMaxUndecryptablePackets) { | |
93 // If there are kMaxBufferedPacketsPerConnection packets buffered up for | |
94 // this connection, drop the current packet. | |
95 return TOO_MANY_PACKETS; | |
96 } | |
97 | |
98 if (queue.buffered_packets.empty()) { | |
99 // If this is the first packet arrived on a new connection, initialize the | |
100 // creation time. | |
101 queue.creation_time = clock_->ApproximateNow(); | |
102 } | |
103 | |
104 BufferedPacket new_entry(std::unique_ptr<QuicEncryptedPacket>(packet.Clone()), | |
105 server_address, client_address); | |
106 | |
107 queue.buffered_packets.push_back(std::move(new_entry)); | |
108 | |
109 if (!expiration_alarm_->IsSet()) { | |
110 expiration_alarm_->Set(clock_->ApproximateNow().Add(connection_life_span_)); | |
111 } | |
112 return SUCCESS; | |
113 } | |
114 | |
115 std::list<BufferedPacket> QuicBufferedPacketStore::DeliverPackets( | |
116 QuicConnectionId connection_id) { | |
117 std::list<BufferedPacket> packets_to_deliver; | |
118 auto it = undecryptable_packets_.find(connection_id); | |
119 if (it != undecryptable_packets_.end()) { | |
120 packets_to_deliver = std::move(it->second.buffered_packets); | |
121 undecryptable_packets_.erase(connection_id); | |
122 } | |
123 return packets_to_deliver; | |
124 } | |
125 | |
126 void QuicBufferedPacketStore::OnExpirationTimeout() { | |
127 QuicTime expiration_time = | |
128 clock_->ApproximateNow().Subtract(connection_life_span_); | |
129 while (!undecryptable_packets_.empty()) { | |
130 auto& entry = undecryptable_packets_.front(); | |
131 if (entry.second.creation_time > expiration_time) { | |
132 break; | |
133 } | |
134 visitor_->OnExpiredPackets(entry.first, std::move(entry.second)); | |
135 undecryptable_packets_.erase(undecryptable_packets_.begin()); | |
136 } | |
137 if (!undecryptable_packets_.empty()) { | |
138 expiration_alarm_->Set(clock_->ApproximateNow().Add(connection_life_span_)); | |
139 } | |
140 } | |
141 | |
142 } // namespace net | |
OLD | NEW |