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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 : epoll_server_(epoll_server), | 98 : epoll_server_(epoll_server), |
99 kTimeWaitPeriod_(QuicTime::Delta::FromSeconds(kTimeWaitSeconds)), | 99 kTimeWaitPeriod_(QuicTime::Delta::FromSeconds(kTimeWaitSeconds)), |
100 guid_clean_up_alarm_(new GuidCleanUpAlarm(this)), | 100 guid_clean_up_alarm_(new GuidCleanUpAlarm(this)), |
101 clock_(epoll_server_), | 101 clock_(epoll_server_), |
102 writer_(writer), | 102 writer_(writer) { |
103 is_write_blocked_(false) { | |
104 SetGuidCleanUpAlarm(); | 103 SetGuidCleanUpAlarm(); |
105 } | 104 } |
106 | 105 |
107 QuicTimeWaitListManager::~QuicTimeWaitListManager() { | 106 QuicTimeWaitListManager::~QuicTimeWaitListManager() { |
108 guid_clean_up_alarm_->UnregisterIfRegistered(); | 107 guid_clean_up_alarm_->UnregisterIfRegistered(); |
109 STLDeleteElements(&time_ordered_guid_list_); | 108 STLDeleteElements(&time_ordered_guid_list_); |
110 STLDeleteElements(&pending_packets_queue_); | 109 STLDeleteElements(&pending_packets_queue_); |
111 for (GuidMapIterator it = guid_map_.begin(); it != guid_map_.end(); ++it) { | 110 for (GuidMapIterator it = guid_map_.begin(); it != guid_map_.end(); ++it) { |
112 delete it->second.close_packet; | 111 delete it->second.close_packet; |
113 } | 112 } |
(...skipping 16 matching lines...) Expand all Loading... |
130 return guid_map_.find(guid) != guid_map_.end(); | 129 return guid_map_.find(guid) != guid_map_.end(); |
131 } | 130 } |
132 | 131 |
133 QuicVersion QuicTimeWaitListManager::GetQuicVersionFromGuid(QuicGuid guid) { | 132 QuicVersion QuicTimeWaitListManager::GetQuicVersionFromGuid(QuicGuid guid) { |
134 GuidMapIterator it = guid_map_.find(guid); | 133 GuidMapIterator it = guid_map_.find(guid); |
135 DCHECK(it != guid_map_.end()); | 134 DCHECK(it != guid_map_.end()); |
136 return (it->second).version; | 135 return (it->second).version; |
137 } | 136 } |
138 | 137 |
139 bool QuicTimeWaitListManager::OnCanWrite() { | 138 bool QuicTimeWaitListManager::OnCanWrite() { |
140 is_write_blocked_ = false; | 139 while (!pending_packets_queue_.empty()) { |
141 while (!is_write_blocked_ && !pending_packets_queue_.empty()) { | |
142 QueuedPacket* queued_packet = pending_packets_queue_.front(); | 140 QueuedPacket* queued_packet = pending_packets_queue_.front(); |
143 WriteToWire(queued_packet); | 141 if (WriteToWire(queued_packet)) { |
144 if (!is_write_blocked_) { | |
145 pending_packets_queue_.pop_front(); | 142 pending_packets_queue_.pop_front(); |
146 delete queued_packet; | 143 delete queued_packet; |
| 144 } else { |
| 145 break; |
147 } | 146 } |
148 } | 147 } |
149 | 148 |
150 return !is_write_blocked_; | 149 return !writer_->IsWriteBlocked(); |
151 } | 150 } |
152 | 151 |
153 void QuicTimeWaitListManager::ProcessPacket( | 152 void QuicTimeWaitListManager::ProcessPacket( |
154 const IPEndPoint& server_address, | 153 const IPEndPoint& server_address, |
155 const IPEndPoint& client_address, | 154 const IPEndPoint& client_address, |
156 QuicGuid guid, | 155 QuicGuid guid, |
157 QuicPacketSequenceNumber sequence_number) { | 156 QuicPacketSequenceNumber sequence_number) { |
158 DCHECK(IsGuidInTimeWait(guid)); | 157 DCHECK(IsGuidInTimeWait(guid)); |
159 // TODO(satyamshekhar): Think about handling packets from different client | 158 // TODO(satyamshekhar): Think about handling packets from different client |
160 // addresses. | 159 // addresses. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 server_address, | 198 server_address, |
200 client_address, | 199 client_address, |
201 QuicFramer::BuildPublicResetPacket(packet)); | 200 QuicFramer::BuildPublicResetPacket(packet)); |
202 // Takes ownership of the packet. | 201 // Takes ownership of the packet. |
203 SendOrQueuePacket(queued_packet); | 202 SendOrQueuePacket(queued_packet); |
204 } | 203 } |
205 | 204 |
206 // Either sends the packet and deletes it or makes pending queue the | 205 // Either sends the packet and deletes it or makes pending queue the |
207 // owner of the packet. | 206 // owner of the packet. |
208 void QuicTimeWaitListManager::SendOrQueuePacket(QueuedPacket* packet) { | 207 void QuicTimeWaitListManager::SendOrQueuePacket(QueuedPacket* packet) { |
209 if (!is_write_blocked_) { | 208 if (WriteToWire(packet)) { |
210 // TODO(satyamshekhar): Handle packets that fail due to error other than | 209 delete packet; |
211 // EAGAIN or EWOULDBLOCK. | 210 } else { |
212 WriteToWire(packet); | |
213 } | |
214 | |
215 if (is_write_blocked_) { | |
216 // pending_packets_queue takes the ownership of the queued packet. | 211 // pending_packets_queue takes the ownership of the queued packet. |
217 pending_packets_queue_.push_back(packet); | 212 pending_packets_queue_.push_back(packet); |
218 } else { | |
219 delete packet; | |
220 } | 213 } |
221 } | 214 } |
222 | 215 |
223 void QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) { | 216 bool QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) { |
224 DCHECK(!is_write_blocked_); | 217 if (writer_->IsWriteBlocked()) { |
| 218 return false; |
| 219 } |
225 WriteResult result = writer_->WritePacket( | 220 WriteResult result = writer_->WritePacket( |
226 queued_packet->packet()->data(), | 221 queued_packet->packet()->data(), |
227 queued_packet->packet()->length(), | 222 queued_packet->packet()->length(), |
228 queued_packet->server_address().address(), | 223 queued_packet->server_address().address(), |
229 queued_packet->client_address(), | 224 queued_packet->client_address(), |
230 this); | 225 this); |
231 if (result.status == WRITE_STATUS_BLOCKED) { | 226 if (result.status == WRITE_STATUS_BLOCKED) { |
232 is_write_blocked_ = true; | 227 // If blocked and unbuffered, return false to retry sending. |
| 228 DCHECK(writer_->IsWriteBlocked()); |
| 229 return writer_->IsWriteBlockedDataBuffered(); |
233 } else if (result.status == WRITE_STATUS_ERROR) { | 230 } else if (result.status == WRITE_STATUS_ERROR) { |
234 LOG(WARNING) << "Received unknown error while sending reset packet to " | 231 LOG(WARNING) << "Received unknown error while sending reset packet to " |
235 << queued_packet->client_address().ToString() << ": " | 232 << queued_packet->client_address().ToString() << ": " |
236 << strerror(result.error_code); | 233 << strerror(result.error_code); |
237 } | 234 } |
| 235 return true; |
238 } | 236 } |
239 | 237 |
240 void QuicTimeWaitListManager::SetGuidCleanUpAlarm() { | 238 void QuicTimeWaitListManager::SetGuidCleanUpAlarm() { |
241 guid_clean_up_alarm_->UnregisterIfRegistered(); | 239 guid_clean_up_alarm_->UnregisterIfRegistered(); |
242 int64 next_alarm_interval; | 240 int64 next_alarm_interval; |
243 if (!time_ordered_guid_list_.empty()) { | 241 if (!time_ordered_guid_list_.empty()) { |
244 GuidAddTime* oldest_guid = time_ordered_guid_list_.front(); | 242 GuidAddTime* oldest_guid = time_ordered_guid_list_.front(); |
245 QuicTime now = clock_.ApproximateNow(); | 243 QuicTime now = clock_.ApproximateNow(); |
246 DCHECK(now.Subtract(oldest_guid->time_added) < kTimeWaitPeriod_); | 244 DCHECK(now.Subtract(oldest_guid->time_added) < kTimeWaitPeriod_); |
247 next_alarm_interval = oldest_guid->time_added | 245 next_alarm_interval = oldest_guid->time_added |
(...skipping 23 matching lines...) Expand all Loading... |
271 delete it->second.close_packet; | 269 delete it->second.close_packet; |
272 guid_map_.erase(oldest_guid->guid); | 270 guid_map_.erase(oldest_guid->guid); |
273 time_ordered_guid_list_.pop_front(); | 271 time_ordered_guid_list_.pop_front(); |
274 delete oldest_guid; | 272 delete oldest_guid; |
275 } | 273 } |
276 SetGuidCleanUpAlarm(); | 274 SetGuidCleanUpAlarm(); |
277 } | 275 } |
278 | 276 |
279 } // namespace tools | 277 } // namespace tools |
280 } // namespace net | 278 } // namespace net |
OLD | NEW |