OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/tools/quic/quic_time_wait_list_manager.h" | 5 #include "net/tools/quic/quic_time_wait_list_manager.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 | 8 |
9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 const IPEndPoint client_address_; | 88 const IPEndPoint client_address_; |
89 scoped_ptr<QuicEncryptedPacket> packet_; | 89 scoped_ptr<QuicEncryptedPacket> packet_; |
90 | 90 |
91 DISALLOW_COPY_AND_ASSIGN(QueuedPacket); | 91 DISALLOW_COPY_AND_ASSIGN(QueuedPacket); |
92 }; | 92 }; |
93 | 93 |
94 QuicTimeWaitListManager::QuicTimeWaitListManager( | 94 QuicTimeWaitListManager::QuicTimeWaitListManager( |
95 QuicPacketWriter* writer, | 95 QuicPacketWriter* writer, |
96 EpollServer* epoll_server, | 96 EpollServer* epoll_server, |
97 const QuicVersionVector& supported_versions) | 97 const QuicVersionVector& supported_versions) |
98 : framer_(supported_versions, | 98 : epoll_server_(epoll_server), |
99 QuicTime::Zero(), // unused | |
100 true), | |
101 epoll_server_(epoll_server), | |
102 kTimeWaitPeriod_(QuicTime::Delta::FromSeconds(kTimeWaitSeconds)), | 99 kTimeWaitPeriod_(QuicTime::Delta::FromSeconds(kTimeWaitSeconds)), |
103 guid_clean_up_alarm_(new GuidCleanUpAlarm(this)), | 100 guid_clean_up_alarm_(new GuidCleanUpAlarm(this)), |
104 clock_(epoll_server), | 101 clock_(epoll_server_), |
105 writer_(writer), | 102 writer_(writer), |
106 is_write_blocked_(false) { | 103 is_write_blocked_(false) { |
107 framer_.set_visitor(this); | |
108 SetGuidCleanUpAlarm(); | 104 SetGuidCleanUpAlarm(); |
109 } | 105 } |
110 | 106 |
111 QuicTimeWaitListManager::~QuicTimeWaitListManager() { | 107 QuicTimeWaitListManager::~QuicTimeWaitListManager() { |
112 guid_clean_up_alarm_->UnregisterIfRegistered(); | 108 guid_clean_up_alarm_->UnregisterIfRegistered(); |
113 STLDeleteElements(&time_ordered_guid_list_); | 109 STLDeleteElements(&time_ordered_guid_list_); |
114 STLDeleteElements(&pending_packets_queue_); | 110 STLDeleteElements(&pending_packets_queue_); |
115 for (GuidMapIterator it = guid_map_.begin(); it != guid_map_.end(); ++it) { | 111 for (GuidMapIterator it = guid_map_.begin(); it != guid_map_.end(); ++it) { |
116 delete it->second.close_packet; | 112 delete it->second.close_packet; |
117 } | 113 } |
118 } | 114 } |
119 | 115 |
120 void QuicTimeWaitListManager::AddGuidToTimeWait( | 116 void QuicTimeWaitListManager::AddGuidToTimeWait( |
121 QuicGuid guid, | 117 QuicGuid guid, |
122 QuicVersion version, | 118 QuicVersion version, |
123 QuicEncryptedPacket* close_packet) { | 119 QuicEncryptedPacket* close_packet) { |
124 DCHECK(!IsGuidInTimeWait(guid)); | 120 DCHECK(!IsGuidInTimeWait(guid)); |
125 // Initialize the guid with 0 packets received. | 121 // Initialize the guid with 0 packets received. |
126 GuidData data(0, version, close_packet); | 122 GuidData data(0, version, close_packet); |
127 guid_map_.insert(make_pair(guid, data)); | 123 guid_map_.insert(make_pair(guid, data)); |
128 time_ordered_guid_list_.push_back(new GuidAddTime(guid, | 124 time_ordered_guid_list_.push_back(new GuidAddTime(guid, |
129 clock_.ApproximateNow())); | 125 clock_.ApproximateNow())); |
| 126 DCHECK(IsGuidInTimeWait(guid)); |
130 } | 127 } |
131 | 128 |
132 bool QuicTimeWaitListManager::IsGuidInTimeWait(QuicGuid guid) const { | 129 bool QuicTimeWaitListManager::IsGuidInTimeWait(QuicGuid guid) const { |
133 return guid_map_.find(guid) != guid_map_.end(); | 130 return guid_map_.find(guid) != guid_map_.end(); |
134 } | 131 } |
135 | 132 |
136 void QuicTimeWaitListManager::ProcessPacket( | |
137 const IPEndPoint& server_address, | |
138 const IPEndPoint& client_address, | |
139 QuicGuid guid, | |
140 const QuicEncryptedPacket& packet) { | |
141 DCHECK(IsGuidInTimeWait(guid)); | |
142 server_address_ = server_address; | |
143 client_address_ = client_address; | |
144 | |
145 // Set the framer to the appropriate version for this GUID, before processing. | |
146 QuicVersion version = GetQuicVersionFromGuid(guid); | |
147 framer_.set_version(version); | |
148 | |
149 framer_.ProcessPacket(packet); | |
150 } | |
151 | |
152 QuicVersion QuicTimeWaitListManager::GetQuicVersionFromGuid(QuicGuid guid) { | 133 QuicVersion QuicTimeWaitListManager::GetQuicVersionFromGuid(QuicGuid guid) { |
153 GuidMapIterator it = guid_map_.find(guid); | 134 GuidMapIterator it = guid_map_.find(guid); |
154 DCHECK(it != guid_map_.end()); | 135 DCHECK(it != guid_map_.end()); |
155 return (it->second).version; | 136 return (it->second).version; |
156 } | 137 } |
157 | 138 |
158 bool QuicTimeWaitListManager::OnCanWrite() { | 139 bool QuicTimeWaitListManager::OnCanWrite() { |
159 is_write_blocked_ = false; | 140 is_write_blocked_ = false; |
160 while (!is_write_blocked_ && !pending_packets_queue_.empty()) { | 141 while (!is_write_blocked_ && !pending_packets_queue_.empty()) { |
161 QueuedPacket* queued_packet = pending_packets_queue_.front(); | 142 QueuedPacket* queued_packet = pending_packets_queue_.front(); |
162 WriteToWire(queued_packet); | 143 WriteToWire(queued_packet); |
163 if (!is_write_blocked_) { | 144 if (!is_write_blocked_) { |
164 pending_packets_queue_.pop_front(); | 145 pending_packets_queue_.pop_front(); |
165 delete queued_packet; | 146 delete queued_packet; |
166 } | 147 } |
167 } | 148 } |
168 | 149 |
169 return !is_write_blocked_; | 150 return !is_write_blocked_; |
170 } | 151 } |
171 | 152 |
172 void QuicTimeWaitListManager::OnError(QuicFramer* framer) { | 153 void QuicTimeWaitListManager::ProcessPacket( |
173 DLOG(INFO) << QuicUtils::ErrorToString(framer->error()); | 154 const IPEndPoint& server_address, |
174 } | 155 const IPEndPoint& client_address, |
175 | 156 QuicGuid guid, |
176 bool QuicTimeWaitListManager::OnProtocolVersionMismatch( | 157 QuicPacketSequenceNumber sequence_number) { |
177 QuicVersion received_version) { | 158 DCHECK(IsGuidInTimeWait(guid)); |
178 if (!framer_.IsSupportedVersion(received_version)) { | |
179 // Drop such packets whose version don't match. | |
180 return false; | |
181 } | |
182 // Allow the framer to continue processing this packet. | |
183 framer_.set_version(received_version); | |
184 return true; | |
185 } | |
186 | |
187 bool QuicTimeWaitListManager::OnUnauthenticatedHeader( | |
188 const QuicPacketHeader& header) { | |
189 // TODO(satyamshekhar): Think about handling packets from different client | 159 // TODO(satyamshekhar): Think about handling packets from different client |
190 // addresses. | 160 // addresses. |
191 GuidMapIterator it = guid_map_.find(header.public_header.guid); | 161 GuidMapIterator it = guid_map_.find(guid); |
192 DCHECK(it != guid_map_.end()); | 162 DCHECK(it != guid_map_.end()); |
193 // Increment the received packet count. | 163 // Increment the received packet count. |
194 ++((it->second).num_packets); | 164 ++((it->second).num_packets); |
195 if (!ShouldSendResponse((it->second).num_packets)) { | 165 if (!ShouldSendResponse((it->second).num_packets)) { |
196 return false; | 166 return; |
197 } | 167 } |
198 if (it->second.close_packet) { | 168 if (it->second.close_packet) { |
199 QueuedPacket* queued_packet = | 169 QueuedPacket* queued_packet = |
200 new QueuedPacket(server_address_, | 170 new QueuedPacket(server_address, |
201 client_address_, | 171 client_address, |
202 it->second.close_packet->Clone()); | 172 it->second.close_packet->Clone()); |
203 // Takes ownership of the packet. | 173 // Takes ownership of the packet. |
204 SendOrQueuePacket(queued_packet); | 174 SendOrQueuePacket(queued_packet); |
205 } else { | 175 } else { |
206 // We don't need the packet anymore. Just tell the client what sequence | 176 SendPublicReset(server_address, client_address, guid, sequence_number); |
207 // number we rejected. | |
208 SendPublicReset(server_address_, | |
209 client_address_, | |
210 header.public_header.guid, | |
211 header.packet_sequence_number); | |
212 } | 177 } |
213 // Never process the body of the packet in time wait state. | |
214 return false; | |
215 } | |
216 | |
217 bool QuicTimeWaitListManager::OnPacketHeader(const QuicPacketHeader& header) { | |
218 DCHECK(false); | |
219 return false; | |
220 } | |
221 | |
222 void QuicTimeWaitListManager::OnRevivedPacket() { | |
223 DCHECK(false); | |
224 } | |
225 | |
226 void QuicTimeWaitListManager::OnFecProtectedPayload(StringPiece /*payload*/) { | |
227 DCHECK(false); | |
228 } | |
229 | |
230 bool QuicTimeWaitListManager::OnStreamFrame(const QuicStreamFrame& /*frame*/) { | |
231 DCHECK(false); | |
232 return false; | |
233 } | |
234 | |
235 bool QuicTimeWaitListManager::OnAckFrame(const QuicAckFrame& /*frame*/) { | |
236 DCHECK(false); | |
237 return false; | |
238 } | |
239 | |
240 bool QuicTimeWaitListManager::OnCongestionFeedbackFrame( | |
241 const QuicCongestionFeedbackFrame& /*frame*/) { | |
242 DCHECK(false); | |
243 return false; | |
244 } | |
245 | |
246 bool QuicTimeWaitListManager::OnRstStreamFrame( | |
247 const QuicRstStreamFrame& /*frame*/) { | |
248 DCHECK(false); | |
249 return false; | |
250 } | |
251 | |
252 bool QuicTimeWaitListManager::OnConnectionCloseFrame( | |
253 const QuicConnectionCloseFrame & /*frame*/) { | |
254 DCHECK(false); | |
255 return false; | |
256 } | |
257 | |
258 bool QuicTimeWaitListManager::OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) { | |
259 DCHECK(false); | |
260 return false; | |
261 } | |
262 | |
263 void QuicTimeWaitListManager::OnFecData(const QuicFecData& /*fec*/) { | |
264 DCHECK(false); | |
265 } | 178 } |
266 | 179 |
267 // Returns true if the number of packets received for this guid is a power of 2 | 180 // Returns true if the number of packets received for this guid is a power of 2 |
268 // to throttle the number of public reset packets we send to a client. | 181 // to throttle the number of public reset packets we send to a client. |
269 bool QuicTimeWaitListManager::ShouldSendResponse(int received_packet_count) { | 182 bool QuicTimeWaitListManager::ShouldSendResponse(int received_packet_count) { |
270 return (received_packet_count & (received_packet_count - 1)) == 0; | 183 return (received_packet_count & (received_packet_count - 1)) == 0; |
271 } | 184 } |
272 | 185 |
273 void QuicTimeWaitListManager::SendPublicReset( | 186 void QuicTimeWaitListManager::SendPublicReset( |
274 const IPEndPoint& server_address, | 187 const IPEndPoint& server_address, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 } | 221 } |
309 | 222 |
310 void QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) { | 223 void QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) { |
311 DCHECK(!is_write_blocked_); | 224 DCHECK(!is_write_blocked_); |
312 WriteResult result = writer_->WritePacket( | 225 WriteResult result = writer_->WritePacket( |
313 queued_packet->packet()->data(), | 226 queued_packet->packet()->data(), |
314 queued_packet->packet()->length(), | 227 queued_packet->packet()->length(), |
315 queued_packet->server_address().address(), | 228 queued_packet->server_address().address(), |
316 queued_packet->client_address(), | 229 queued_packet->client_address(), |
317 this); | 230 this); |
318 | |
319 if (result.status == WRITE_STATUS_BLOCKED) { | 231 if (result.status == WRITE_STATUS_BLOCKED) { |
320 is_write_blocked_ = true; | 232 is_write_blocked_ = true; |
321 } else if (result.status == WRITE_STATUS_ERROR) { | 233 } else if (result.status == WRITE_STATUS_ERROR) { |
322 LOG(WARNING) << "Received unknown error while sending reset packet to " | 234 LOG(WARNING) << "Received unknown error while sending reset packet to " |
323 << queued_packet->client_address().ToString() << ": " | 235 << queued_packet->client_address().ToString() << ": " |
324 << strerror(result.error_code); | 236 << strerror(result.error_code); |
325 } | 237 } |
326 } | 238 } |
327 | 239 |
328 void QuicTimeWaitListManager::SetGuidCleanUpAlarm() { | 240 void QuicTimeWaitListManager::SetGuidCleanUpAlarm() { |
(...skipping 30 matching lines...) Expand all Loading... |
359 delete it->second.close_packet; | 271 delete it->second.close_packet; |
360 guid_map_.erase(oldest_guid->guid); | 272 guid_map_.erase(oldest_guid->guid); |
361 time_ordered_guid_list_.pop_front(); | 273 time_ordered_guid_list_.pop_front(); |
362 delete oldest_guid; | 274 delete oldest_guid; |
363 } | 275 } |
364 SetGuidCleanUpAlarm(); | 276 SetGuidCleanUpAlarm(); |
365 } | 277 } |
366 | 278 |
367 } // namespace tools | 279 } // namespace tools |
368 } // namespace net | 280 } // namespace net |
OLD | NEW |