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 |