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/quic/quic_connection.h" | 5 #include "net/quic/quic_connection.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 #include <sys/types.h> | 8 #include <sys/types.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 class MtuDiscoveryAckListener : public QuicAckNotifier::DelegateInterface { | 200 class MtuDiscoveryAckListener : public QuicAckNotifier::DelegateInterface { |
201 public: | 201 public: |
202 MtuDiscoveryAckListener(QuicConnection* connection, QuicByteCount probe_size) | 202 MtuDiscoveryAckListener(QuicConnection* connection, QuicByteCount probe_size) |
203 : connection_(connection), probe_size_(probe_size) {} | 203 : connection_(connection), probe_size_(probe_size) {} |
204 | 204 |
205 void OnAckNotification(int /*num_retransmittable_packets*/, | 205 void OnAckNotification(int /*num_retransmittable_packets*/, |
206 int /*num_retransmittable_bytes*/, | 206 int /*num_retransmittable_bytes*/, |
207 QuicTime::Delta /*delta_largest_observed*/) override { | 207 QuicTime::Delta /*delta_largest_observed*/) override { |
208 // Since the probe was successful, increase the maximum packet size to that. | 208 // Since the probe was successful, increase the maximum packet size to that. |
209 if (probe_size_ > connection_->max_packet_length()) { | 209 if (probe_size_ > connection_->max_packet_length()) { |
210 connection_->set_max_packet_length(probe_size_); | 210 connection_->SetMaxPacketLength(probe_size_); |
211 } | 211 } |
212 } | 212 } |
213 | 213 |
214 protected: | 214 protected: |
215 // MtuDiscoveryAckListener is ref counted. | 215 // MtuDiscoveryAckListener is ref counted. |
216 ~MtuDiscoveryAckListener() override {} | 216 ~MtuDiscoveryAckListener() override {} |
217 | 217 |
218 private: | 218 private: |
219 QuicConnection* connection_; | 219 QuicConnection* connection_; |
220 QuicByteCount probe_size_; | 220 QuicByteCount probe_size_; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 next_mtu_probe_at_(kPacketsBetweenMtuProbesBase), | 320 next_mtu_probe_at_(kPacketsBetweenMtuProbesBase), |
321 largest_received_packet_size_(0), | 321 largest_received_packet_size_(0), |
322 goaway_sent_(false), | 322 goaway_sent_(false), |
323 goaway_received_(false) { | 323 goaway_received_(false) { |
324 DVLOG(1) << ENDPOINT << "Created connection with connection_id: " | 324 DVLOG(1) << ENDPOINT << "Created connection with connection_id: " |
325 << connection_id; | 325 << connection_id; |
326 framer_.set_visitor(this); | 326 framer_.set_visitor(this); |
327 framer_.set_received_entropy_calculator(&received_packet_manager_); | 327 framer_.set_received_entropy_calculator(&received_packet_manager_); |
328 stats_.connection_creation_time = clock_->ApproximateNow(); | 328 stats_.connection_creation_time = clock_->ApproximateNow(); |
329 sent_packet_manager_.set_network_change_visitor(this); | 329 sent_packet_manager_.set_network_change_visitor(this); |
330 if (perspective_ == Perspective::IS_SERVER) { | 330 // Allow the packet writer to potentially reduce the packet size to a value |
331 set_max_packet_length(kDefaultServerMaxPacketSize); | 331 // even smaller than kDefaultMaxPacketSize. |
332 } | 332 SetMaxPacketLength(perspective_ == Perspective::IS_SERVER |
| 333 ? kDefaultServerMaxPacketSize |
| 334 : kDefaultMaxPacketSize); |
333 } | 335 } |
334 | 336 |
335 QuicConnection::~QuicConnection() { | 337 QuicConnection::~QuicConnection() { |
336 if (owns_writer_) { | 338 if (owns_writer_) { |
337 delete writer_; | 339 delete writer_; |
338 } | 340 } |
339 STLDeleteElements(&undecryptable_packets_); | 341 STLDeleteElements(&undecryptable_packets_); |
340 STLDeleteValues(&group_map_); | 342 STLDeleteValues(&group_map_); |
341 ClearQueuedPackets(); | 343 ClearQueuedPackets(); |
342 } | 344 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 packet_generator_.set_fec_send_policy(FecSendPolicy::FEC_ALARM_TRIGGER); | 376 packet_generator_.set_fec_send_policy(FecSendPolicy::FEC_ALARM_TRIGGER); |
375 } | 377 } |
376 if (config.HasClientSentConnectionOption(kFRTT, perspective_)) { | 378 if (config.HasClientSentConnectionOption(kFRTT, perspective_)) { |
377 // TODO(rtenneti): Delete this code after the 0.25 RTT FEC experiment. | 379 // TODO(rtenneti): Delete this code after the 0.25 RTT FEC experiment. |
378 const float kFecTimeoutRttMultiplier = 0.25; | 380 const float kFecTimeoutRttMultiplier = 0.25; |
379 packet_generator_.set_rtt_multiplier_for_fec_timeout( | 381 packet_generator_.set_rtt_multiplier_for_fec_timeout( |
380 kFecTimeoutRttMultiplier); | 382 kFecTimeoutRttMultiplier); |
381 } | 383 } |
382 | 384 |
383 if (config.HasClientSentConnectionOption(kMTUH, perspective_)) { | 385 if (config.HasClientSentConnectionOption(kMTUH, perspective_)) { |
384 mtu_discovery_target_ = kMtuDiscoveryTargetPacketSizeHigh; | 386 SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh); |
385 } | 387 } |
386 if (config.HasClientSentConnectionOption(kMTUL, perspective_)) { | 388 if (config.HasClientSentConnectionOption(kMTUL, perspective_)) { |
387 mtu_discovery_target_ = kMtuDiscoveryTargetPacketSizeLow; | 389 SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeLow); |
388 } | 390 } |
389 } | 391 } |
390 | 392 |
391 void QuicConnection::OnSendConnectionState( | 393 void QuicConnection::OnSendConnectionState( |
392 const CachedNetworkParameters& cached_network_params) { | 394 const CachedNetworkParameters& cached_network_params) { |
393 if (debug_visitor_ != nullptr) { | 395 if (debug_visitor_ != nullptr) { |
394 debug_visitor_->OnSendConnectionState(cached_network_params); | 396 debug_visitor_->OnSendConnectionState(cached_network_params); |
395 } | 397 } |
396 } | 398 } |
397 | 399 |
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1410 | 1412 |
1411 // Store in case we want to migrate connection in ProcessValidatedPacket. | 1413 // Store in case we want to migrate connection in ProcessValidatedPacket. |
1412 migrating_peer_ip_ = peer_address.address(); | 1414 migrating_peer_ip_ = peer_address.address(); |
1413 migrating_peer_port_ = peer_address.port(); | 1415 migrating_peer_port_ = peer_address.port(); |
1414 } | 1416 } |
1415 | 1417 |
1416 if (!self_address.address().empty() && !self_address_.address().empty()) { | 1418 if (!self_address.address().empty() && !self_address_.address().empty()) { |
1417 self_ip_changed_ = (self_address.address() != self_address_.address()); | 1419 self_ip_changed_ = (self_address.address() != self_address_.address()); |
1418 self_port_changed_ = (self_address.port() != self_address_.port()); | 1420 self_port_changed_ = (self_address.port() != self_address_.port()); |
1419 } | 1421 } |
| 1422 |
| 1423 // TODO(vasilvv): reset maximum packet size on connection migration. Whenever |
| 1424 // the connection is migrated, it usually ends up being on a different path, |
| 1425 // with possibly smaller MTU. This means the max packet size has to be reset |
| 1426 // and MTU discovery mechanism re-initialized. The main reason the code does |
| 1427 // not do it now is that the retransmission code currently cannot deal with |
| 1428 // the case when it needs to resend a packet created with larger MTU (see |
| 1429 // b/22172803). |
1420 } | 1430 } |
1421 | 1431 |
1422 void QuicConnection::OnCanWrite() { | 1432 void QuicConnection::OnCanWrite() { |
1423 DCHECK(!writer_->IsWriteBlocked()); | 1433 DCHECK(!writer_->IsWriteBlocked()); |
1424 | 1434 |
1425 WriteQueuedPackets(); | 1435 WriteQueuedPackets(); |
1426 WritePendingRetransmissions(); | 1436 WritePendingRetransmissions(); |
1427 | 1437 |
1428 // Sending queued packets may have caused the socket to become write blocked, | 1438 // Sending queued packets may have caused the socket to become write blocked, |
1429 // or the congestion manager to prohibit sending. If we've sent everything | 1439 // or the congestion manager to prohibit sending. If we've sent everything |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1484 DVLOG(1) << ENDPOINT << "time of last received packet: " | 1494 DVLOG(1) << ENDPOINT << "time of last received packet: " |
1485 << time_of_last_received_packet_.ToDebuggingValue(); | 1495 << time_of_last_received_packet_.ToDebuggingValue(); |
1486 | 1496 |
1487 if (last_size_ > largest_received_packet_size_) { | 1497 if (last_size_ > largest_received_packet_size_) { |
1488 largest_received_packet_size_ = last_size_; | 1498 largest_received_packet_size_ = last_size_; |
1489 } | 1499 } |
1490 | 1500 |
1491 if (perspective_ == Perspective::IS_SERVER && | 1501 if (perspective_ == Perspective::IS_SERVER && |
1492 encryption_level_ == ENCRYPTION_NONE && | 1502 encryption_level_ == ENCRYPTION_NONE && |
1493 last_size_ > packet_generator_.GetMaxPacketLength()) { | 1503 last_size_ > packet_generator_.GetMaxPacketLength()) { |
1494 set_max_packet_length(last_size_); | 1504 SetMaxPacketLength(last_size_); |
1495 } | 1505 } |
1496 return true; | 1506 return true; |
1497 } | 1507 } |
1498 | 1508 |
1499 void QuicConnection::WriteQueuedPackets() { | 1509 void QuicConnection::WriteQueuedPackets() { |
1500 DCHECK(!writer_->IsWriteBlocked()); | 1510 DCHECK(!writer_->IsWriteBlocked()); |
1501 | 1511 |
1502 if (pending_version_negotiation_packet_) { | 1512 if (pending_version_negotiation_packet_) { |
1503 SendVersionNegotiationPacket(); | 1513 SendVersionNegotiationPacket(); |
1504 } | 1514 } |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2136 group_map_.erase(it); | 2146 group_map_.erase(it); |
2137 delete fec_group; | 2147 delete fec_group; |
2138 it = next; | 2148 it = next; |
2139 } | 2149 } |
2140 } | 2150 } |
2141 | 2151 |
2142 QuicByteCount QuicConnection::max_packet_length() const { | 2152 QuicByteCount QuicConnection::max_packet_length() const { |
2143 return packet_generator_.GetMaxPacketLength(); | 2153 return packet_generator_.GetMaxPacketLength(); |
2144 } | 2154 } |
2145 | 2155 |
2146 void QuicConnection::set_max_packet_length(QuicByteCount length) { | 2156 void QuicConnection::SetMaxPacketLength(QuicByteCount length) { |
2147 return packet_generator_.SetMaxPacketLength(length, /*force=*/false); | 2157 return packet_generator_.SetMaxPacketLength(LimitMaxPacketSize(length), |
| 2158 /*force=*/false); |
2148 } | 2159 } |
2149 | 2160 |
2150 bool QuicConnection::HasQueuedData() const { | 2161 bool QuicConnection::HasQueuedData() const { |
2151 return pending_version_negotiation_packet_ || | 2162 return pending_version_negotiation_packet_ || |
2152 !queued_packets_.empty() || packet_generator_.HasQueuedFrames(); | 2163 !queued_packets_.empty() || packet_generator_.HasQueuedFrames(); |
2153 } | 2164 } |
2154 | 2165 |
2155 bool QuicConnection::CanWriteStreamData() { | 2166 bool QuicConnection::CanWriteStreamData() { |
2156 // Don't write stream data if there are negotiation or queued data packets | 2167 // Don't write stream data if there are negotiation or queued data packets |
2157 // to send. Otherwise, continue and bundle as many frames as possible. | 2168 // to send. Otherwise, continue and bundle as many frames as possible. |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2367 return false; | 2378 return false; |
2368 } | 2379 } |
2369 for (const QuicFrame& frame : retransmittable_frames->frames()) { | 2380 for (const QuicFrame& frame : retransmittable_frames->frames()) { |
2370 if (frame.type == CONNECTION_CLOSE_FRAME) { | 2381 if (frame.type == CONNECTION_CLOSE_FRAME) { |
2371 return true; | 2382 return true; |
2372 } | 2383 } |
2373 } | 2384 } |
2374 return false; | 2385 return false; |
2375 } | 2386 } |
2376 | 2387 |
| 2388 void QuicConnection::SetMtuDiscoveryTarget(QuicByteCount target) { |
| 2389 mtu_discovery_target_ = LimitMaxPacketSize(target); |
| 2390 } |
| 2391 |
| 2392 QuicByteCount QuicConnection::LimitMaxPacketSize( |
| 2393 QuicByteCount suggested_max_packet_size) { |
| 2394 if (FLAGS_quic_allow_oversized_packets_for_test) { |
| 2395 return suggested_max_packet_size; |
| 2396 } |
| 2397 |
| 2398 if (!FLAGS_quic_limit_mtu_by_writer) { |
| 2399 return suggested_max_packet_size; |
| 2400 } |
| 2401 |
| 2402 if (peer_address_.address().empty()) { |
| 2403 LOG(DFATAL) << "Attempted to use a connection without a valid peer address"; |
| 2404 return suggested_max_packet_size; |
| 2405 } |
| 2406 |
| 2407 const QuicByteCount writer_limit = writer_->GetMaxPacketSize(peer_address()); |
| 2408 |
| 2409 QuicByteCount max_packet_size = suggested_max_packet_size; |
| 2410 if (max_packet_size > writer_limit) { |
| 2411 max_packet_size = writer_limit; |
| 2412 } |
| 2413 if (max_packet_size > kMaxPacketSize) { |
| 2414 max_packet_size = kMaxPacketSize; |
| 2415 } |
| 2416 return max_packet_size; |
| 2417 } |
| 2418 |
2377 void QuicConnection::SendMtuDiscoveryPacket(QuicByteCount target_mtu) { | 2419 void QuicConnection::SendMtuDiscoveryPacket(QuicByteCount target_mtu) { |
| 2420 // Currently, this limit is ensured by the caller. |
| 2421 DCHECK_EQ(target_mtu, LimitMaxPacketSize(target_mtu)); |
| 2422 |
2378 // Create a listener for the new probe. The ownership of the listener is | 2423 // Create a listener for the new probe. The ownership of the listener is |
2379 // transferred to the AckNotifierManager. The notifier will get destroyed | 2424 // transferred to the AckNotifierManager. The notifier will get destroyed |
2380 // before the connection (because it's stored in one of the connection's | 2425 // before the connection (because it's stored in one of the connection's |
2381 // subfields), hence |this| pointer is guaranteed to stay valid at all times. | 2426 // subfields), hence |this| pointer is guaranteed to stay valid at all times. |
2382 scoped_refptr<MtuDiscoveryAckListener> last_mtu_discovery_ack_listener( | 2427 scoped_refptr<MtuDiscoveryAckListener> last_mtu_discovery_ack_listener( |
2383 new MtuDiscoveryAckListener(this, target_mtu)); | 2428 new MtuDiscoveryAckListener(this, target_mtu)); |
2384 | 2429 |
2385 // Send the probe. | 2430 // Send the probe. |
2386 packet_generator_.GenerateMtuDiscoveryPacket( | 2431 packet_generator_.GenerateMtuDiscoveryPacket( |
2387 target_mtu, last_mtu_discovery_ack_listener.get()); | 2432 target_mtu, last_mtu_discovery_ack_listener.get()); |
(...skipping 16 matching lines...) Expand all Loading... |
2404 packet_number_of_last_sent_packet_ + packets_between_mtu_probes_ + 1; | 2449 packet_number_of_last_sent_packet_ + packets_between_mtu_probes_ + 1; |
2405 ++mtu_probe_count_; | 2450 ++mtu_probe_count_; |
2406 | 2451 |
2407 DVLOG(2) << "Sending a path MTU discovery packet #" << mtu_probe_count_; | 2452 DVLOG(2) << "Sending a path MTU discovery packet #" << mtu_probe_count_; |
2408 SendMtuDiscoveryPacket(mtu_discovery_target_); | 2453 SendMtuDiscoveryPacket(mtu_discovery_target_); |
2409 | 2454 |
2410 DCHECK(!mtu_discovery_alarm_->IsSet()); | 2455 DCHECK(!mtu_discovery_alarm_->IsSet()); |
2411 } | 2456 } |
2412 | 2457 |
2413 } // namespace net | 2458 } // namespace net |
OLD | NEW |