| 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 |