| 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/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 for (ConnectionIdMap::iterator it = connection_id_map_.begin(); | 99 for (ConnectionIdMap::iterator it = connection_id_map_.begin(); |
| 100 it != connection_id_map_.end(); | 100 it != connection_id_map_.end(); |
| 101 ++it) { | 101 ++it) { |
| 102 delete it->second.close_packet; | 102 delete it->second.close_packet; |
| 103 } | 103 } |
| 104 } | 104 } |
| 105 | 105 |
| 106 void QuicTimeWaitListManager::AddConnectionIdToTimeWait( | 106 void QuicTimeWaitListManager::AddConnectionIdToTimeWait( |
| 107 QuicConnectionId connection_id, | 107 QuicConnectionId connection_id, |
| 108 QuicVersion version, | 108 QuicVersion version, |
| 109 bool connection_rejected_statelessly, |
| 109 QuicEncryptedPacket* close_packet) { | 110 QuicEncryptedPacket* close_packet) { |
| 111 DCHECK(!connection_rejected_statelessly || !close_packet) |
| 112 << "Connections that were rejected statelessly should not " |
| 113 << "have a close packet. connection_id = " << connection_id; |
| 110 int num_packets = 0; | 114 int num_packets = 0; |
| 111 ConnectionIdMap::iterator it = connection_id_map_.find(connection_id); | 115 ConnectionIdMap::iterator it = connection_id_map_.find(connection_id); |
| 112 const bool new_connection_id = it == connection_id_map_.end(); | 116 const bool new_connection_id = it == connection_id_map_.end(); |
| 113 if (!new_connection_id) { // Replace record if it is reinserted. | 117 if (!new_connection_id) { // Replace record if it is reinserted. |
| 114 num_packets = it->second.num_packets; | 118 num_packets = it->second.num_packets; |
| 115 delete it->second.close_packet; | 119 delete it->second.close_packet; |
| 116 connection_id_map_.erase(it); | 120 connection_id_map_.erase(it); |
| 117 } | 121 } |
| 118 TrimTimeWaitListIfNeeded(); | 122 TrimTimeWaitListIfNeeded(); |
| 119 DCHECK_LT(num_connections(), | 123 DCHECK_LT(num_connections(), |
| 120 static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)); | 124 static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)); |
| 121 ConnectionIdData data(num_packets, | 125 ConnectionIdData data(num_packets, version, clock_->ApproximateNow(), |
| 122 version, | 126 close_packet, connection_rejected_statelessly); |
| 123 clock_->ApproximateNow(), | |
| 124 close_packet); | |
| 125 connection_id_map_.insert(std::make_pair(connection_id, data)); | 127 connection_id_map_.insert(std::make_pair(connection_id, data)); |
| 126 if (new_connection_id) { | 128 if (new_connection_id) { |
| 127 visitor_->OnConnectionAddedToTimeWaitList(connection_id); | 129 visitor_->OnConnectionAddedToTimeWaitList(connection_id); |
| 128 } | 130 } |
| 129 } | 131 } |
| 130 | 132 |
| 131 bool QuicTimeWaitListManager::IsConnectionIdInTimeWait( | 133 bool QuicTimeWaitListManager::IsConnectionIdInTimeWait( |
| 132 QuicConnectionId connection_id) const { | 134 QuicConnectionId connection_id) const { |
| 133 return ContainsKey(connection_id_map_, connection_id); | 135 return ContainsKey(connection_id_map_, connection_id); |
| 134 } | 136 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 157 QuicConnectionId connection_id, | 159 QuicConnectionId connection_id, |
| 158 QuicPacketSequenceNumber sequence_number, | 160 QuicPacketSequenceNumber sequence_number, |
| 159 const QuicEncryptedPacket& /*packet*/) { | 161 const QuicEncryptedPacket& /*packet*/) { |
| 160 DCHECK(IsConnectionIdInTimeWait(connection_id)); | 162 DCHECK(IsConnectionIdInTimeWait(connection_id)); |
| 161 DVLOG(1) << "Processing " << connection_id << " in time wait state."; | 163 DVLOG(1) << "Processing " << connection_id << " in time wait state."; |
| 162 // TODO(satyamshekhar): Think about handling packets from different client | 164 // TODO(satyamshekhar): Think about handling packets from different client |
| 163 // addresses. | 165 // addresses. |
| 164 ConnectionIdMap::iterator it = connection_id_map_.find(connection_id); | 166 ConnectionIdMap::iterator it = connection_id_map_.find(connection_id); |
| 165 DCHECK(it != connection_id_map_.end()); | 167 DCHECK(it != connection_id_map_.end()); |
| 166 // Increment the received packet count. | 168 // Increment the received packet count. |
| 167 ++((it->second).num_packets); | 169 ConnectionIdData* connection_data = &it->second; |
| 168 if (!ShouldSendResponse((it->second).num_packets)) { | 170 ++(connection_data->num_packets); |
| 171 if (!ShouldSendResponse(connection_data->num_packets)) { |
| 169 return; | 172 return; |
| 170 } | 173 } |
| 171 if (it->second.close_packet) { | 174 if (connection_data->close_packet) { |
| 172 QueuedPacket* queued_packet = | 175 QueuedPacket* queued_packet = new QueuedPacket( |
| 173 new QueuedPacket(server_address, | 176 server_address, client_address, connection_data->close_packet->Clone()); |
| 174 client_address, | |
| 175 it->second.close_packet->Clone()); | |
| 176 // Takes ownership of the packet. | 177 // Takes ownership of the packet. |
| 177 SendOrQueuePacket(queued_packet); | 178 SendOrQueuePacket(queued_packet); |
| 178 } else { | 179 } else if (!connection_data->connection_rejected_statelessly) { |
| 179 SendPublicReset(server_address, | 180 SendPublicReset(server_address, |
| 180 client_address, | 181 client_address, |
| 181 connection_id, | 182 connection_id, |
| 182 sequence_number); | 183 sequence_number); |
| 184 } else { |
| 185 DVLOG(3) << "Time wait list not sending response for connection " |
| 186 << connection_id << " due to previous stateless reject."; |
| 183 } | 187 } |
| 184 } | 188 } |
| 185 | 189 |
| 186 // Returns true if the number of packets received for this connection_id is a | 190 // Returns true if the number of packets received for this connection_id is a |
| 187 // power of 2 to throttle the number of public reset packets we send to a | 191 // power of 2 to throttle the number of public reset packets we send to a |
| 188 // client. | 192 // client. |
| 189 bool QuicTimeWaitListManager::ShouldSendResponse(int received_packet_count) { | 193 bool QuicTimeWaitListManager::ShouldSendResponse(int received_packet_count) { |
| 190 return (received_packet_count & (received_packet_count - 1)) == 0; | 194 return (received_packet_count & (received_packet_count - 1)) == 0; |
| 191 } | 195 } |
| 192 | 196 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 return; | 310 return; |
| 307 } | 311 } |
| 308 while (num_connections() >= | 312 while (num_connections() >= |
| 309 static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)) { | 313 static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)) { |
| 310 MaybeExpireOldestConnection(QuicTime::Infinite()); | 314 MaybeExpireOldestConnection(QuicTime::Infinite()); |
| 311 } | 315 } |
| 312 } | 316 } |
| 313 | 317 |
| 314 } // namespace tools | 318 } // namespace tools |
| 315 } // namespace net | 319 } // namespace net |
| OLD | NEW |