Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: net/quic/quic_connection.cc

Issue 1663493003: Postpone checking peer address change after the packet is successfully (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@113259867
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_flags.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
11 #include <iterator> 11 #include <iterator>
12 #include <limits> 12 #include <limits>
13 #include <memory> 13 #include <memory>
14 #include <set> 14 #include <set>
15 #include <utility> 15 #include <utility>
16 16
17 #include "base/format_macros.h" 17 #include "base/format_macros.h"
18 #include "base/logging.h" 18 #include "base/logging.h"
19 #include "base/macros.h" 19 #include "base/macros.h"
20 #include "base/memory/ref_counted.h" 20 #include "base/memory/ref_counted.h"
21 #include "base/metrics/histogram_macros.h" 21 #include "base/metrics/histogram_macros.h"
22 #include "base/stl_util.h" 22 #include "base/stl_util.h"
23 #include "base/strings/stringprintf.h" 23 #include "base/strings/stringprintf.h"
24 #include "net/base/address_family.h"
24 #include "net/base/net_errors.h" 25 #include "net/base/net_errors.h"
25 #include "net/quic/crypto/crypto_protocol.h" 26 #include "net/quic/crypto/crypto_protocol.h"
26 #include "net/quic/crypto/quic_decrypter.h" 27 #include "net/quic/crypto/quic_decrypter.h"
27 #include "net/quic/crypto/quic_encrypter.h" 28 #include "net/quic/crypto/quic_encrypter.h"
28 #include "net/quic/proto/cached_network_parameters.pb.h" 29 #include "net/quic/proto/cached_network_parameters.pb.h"
29 #include "net/quic/quic_bandwidth.h" 30 #include "net/quic/quic_bandwidth.h"
30 #include "net/quic/quic_bug_tracker.h" 31 #include "net/quic/quic_bug_tracker.h"
31 #include "net/quic/quic_config.h" 32 #include "net/quic/quic_config.h"
32 #include "net/quic/quic_fec_group.h" 33 #include "net/quic/quic_fec_group.h"
33 #include "net/quic/quic_flags.h" 34 #include "net/quic/quic_flags.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 // rapidly increasing. 73 // rapidly increasing.
73 const QuicPacketCount kMinReceivedBeforeAckDecimation = 100; 74 const QuicPacketCount kMinReceivedBeforeAckDecimation = 100;
74 // Wait for up to 10 retransmittable packets before sending an ack. 75 // Wait for up to 10 retransmittable packets before sending an ack.
75 const QuicPacketCount kMaxRetransmittablePacketsBeforeAck = 10; 76 const QuicPacketCount kMaxRetransmittablePacketsBeforeAck = 10;
76 77
77 bool Near(QuicPacketNumber a, QuicPacketNumber b) { 78 bool Near(QuicPacketNumber a, QuicPacketNumber b) {
78 QuicPacketNumber delta = (a > b) ? a - b : b - a; 79 QuicPacketNumber delta = (a > b) ? a - b : b - a;
79 return delta <= kMaxPacketGap; 80 return delta <= kMaxPacketGap;
80 } 81 }
81 82
83 bool IsInitializedIPEndPoint(const IPEndPoint& address) {
84 return net::GetAddressFamily(address.address().bytes()) !=
85 net::ADDRESS_FAMILY_UNSPECIFIED;
86 }
87
82 // An alarm that is scheduled to send an ack if a timeout occurs. 88 // An alarm that is scheduled to send an ack if a timeout occurs.
83 class AckAlarm : public QuicAlarm::Delegate { 89 class AckAlarm : public QuicAlarm::Delegate {
84 public: 90 public:
85 explicit AckAlarm(QuicConnection* connection) : connection_(connection) {} 91 explicit AckAlarm(QuicConnection* connection) : connection_(connection) {}
86 92
87 QuicTime OnAlarm() override { 93 QuicTime OnAlarm() override {
88 DCHECK(connection_->ack_frame_updated()); 94 DCHECK(connection_->ack_frame_updated());
89 connection_->SendAck(); 95 connection_->SendAck();
90 return QuicTime::Zero(); 96 return QuicTime::Zero();
91 } 97 }
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 debug_visitor_->OnPacketHeader(header); 664 debug_visitor_->OnPacketHeader(header);
659 } 665 }
660 666
661 // Will be decremented below if we fall through to return true. 667 // Will be decremented below if we fall through to return true.
662 ++stats_.packets_dropped; 668 ++stats_.packets_dropped;
663 669
664 if (!ProcessValidatedPacket(header)) { 670 if (!ProcessValidatedPacket(header)) {
665 return false; 671 return false;
666 } 672 }
667 673
674 MaybeMigrateConnectionToNewPeerAddress();
675
668 --stats_.packets_dropped; 676 --stats_.packets_dropped;
669 DVLOG(1) << ENDPOINT << "Received packet header: " << header; 677 DVLOG(1) << ENDPOINT << "Received packet header: " << header;
670 last_header_ = header; 678 last_header_ = header;
671 DCHECK(connected_); 679 DCHECK(connected_);
672 return true; 680 return true;
673 } 681 }
674 682
675 void QuicConnection::OnFecProtectedPayload(StringPiece payload) { 683 void QuicConnection::OnFecProtectedPayload(StringPiece payload) {
676 DCHECK_EQ(IN_FEC_GROUP, last_header_.is_in_fec_group); 684 DCHECK_EQ(IN_FEC_GROUP, last_header_.is_in_fec_group);
677 DCHECK_NE(0u, last_header_.fec_group); 685 DCHECK_NE(0u, last_header_.fec_group);
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
1252 const IPEndPoint& peer_address, 1260 const IPEndPoint& peer_address,
1253 const QuicEncryptedPacket& packet) { 1261 const QuicEncryptedPacket& packet) {
1254 if (!connected_) { 1262 if (!connected_) {
1255 return; 1263 return;
1256 } 1264 }
1257 if (debug_visitor_ != nullptr) { 1265 if (debug_visitor_ != nullptr) {
1258 debug_visitor_->OnPacketReceived(self_address, peer_address, packet); 1266 debug_visitor_->OnPacketReceived(self_address, peer_address, packet);
1259 } 1267 }
1260 last_size_ = packet.length(); 1268 last_size_ = packet.length();
1261 1269
1262 CheckForAddressMigration(self_address, peer_address); 1270 if (FLAGS_check_peer_address_change_after_decryption) {
1271 last_packet_destination_address_ = self_address;
1272 last_packet_source_address_ = peer_address;
1273 if (!IsInitializedIPEndPoint(self_address_)) {
1274 self_address_ = last_packet_destination_address_;
1275 }
1276 if (!IsInitializedIPEndPoint(peer_address_)) {
1277 peer_address_ = last_packet_source_address_;
1278 }
1279 } else {
1280 CheckForAddressMigration(self_address, peer_address);
1281 }
1263 1282
1264 stats_.bytes_received += packet.length(); 1283 stats_.bytes_received += packet.length();
1265 ++stats_.packets_received; 1284 ++stats_.packets_received;
1266 1285
1267 ScopedRetransmissionScheduler alarm_delayer(this); 1286 ScopedRetransmissionScheduler alarm_delayer(this);
1268 if (!framer_.ProcessPacket(packet)) { 1287 if (!framer_.ProcessPacket(packet)) {
1269 // If we are unable to decrypt this packet, it might be 1288 // If we are unable to decrypt this packet, it might be
1270 // because the CHLO or SHLO packet was lost. 1289 // because the CHLO or SHLO packet was lost.
1271 if (framer_.error() == QUIC_DECRYPTION_FAILURE) { 1290 if (framer_.error() == QUIC_DECRYPTION_FAILURE) {
1272 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE && 1291 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE &&
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 1326
1308 // Store in case we want to migrate connection in ProcessValidatedPacket. 1327 // Store in case we want to migrate connection in ProcessValidatedPacket.
1309 migrating_peer_ip_ = peer_address.address().bytes(); 1328 migrating_peer_ip_ = peer_address.address().bytes();
1310 migrating_peer_port_ = peer_address.port(); 1329 migrating_peer_port_ = peer_address.port();
1311 } 1330 }
1312 1331
1313 if (!self_address.address().empty() && !self_address_.address().empty()) { 1332 if (!self_address.address().empty() && !self_address_.address().empty()) {
1314 self_ip_changed_ = (self_address.address() != self_address_.address()); 1333 self_ip_changed_ = (self_address.address() != self_address_.address());
1315 self_port_changed_ = (self_address.port() != self_address_.port()); 1334 self_port_changed_ = (self_address.port() != self_address_.port());
1316 } 1335 }
1317
1318 // TODO(vasilvv): reset maximum packet size on connection migration. Whenever
1319 // the connection is migrated, it usually ends up being on a different path,
1320 // with possibly smaller MTU. This means the max packet size has to be reset
1321 // and MTU discovery mechanism re-initialized. The main reason the code does
1322 // not do it now is that the retransmission code currently cannot deal with
1323 // the case when it needs to resend a packet created with larger MTU (see
1324 // b/22172803).
1325 } 1336 }
1326 1337
1327 void QuicConnection::OnCanWrite() { 1338 void QuicConnection::OnCanWrite() {
1328 DCHECK(!writer_->IsWriteBlocked()); 1339 DCHECK(!writer_->IsWriteBlocked());
1329 1340
1330 WriteQueuedPackets(); 1341 WriteQueuedPackets();
1331 WritePendingRetransmissions(); 1342 WritePendingRetransmissions();
1332 1343
1333 // Sending queued packets may have caused the socket to become write blocked, 1344 // Sending queued packets may have caused the socket to become write blocked,
1334 // or the congestion manager to prohibit sending. If we've sent everything 1345 // or the congestion manager to prohibit sending. If we've sent everything
(...skipping 20 matching lines...) Expand all
1355 } 1366 }
1356 } 1367 }
1357 1368
1358 void QuicConnection::WriteIfNotBlocked() { 1369 void QuicConnection::WriteIfNotBlocked() {
1359 if (!writer_->IsWriteBlocked()) { 1370 if (!writer_->IsWriteBlocked()) {
1360 OnCanWrite(); 1371 OnCanWrite();
1361 } 1372 }
1362 } 1373 }
1363 1374
1364 bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) { 1375 bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
1365 if (self_ip_changed_ || self_port_changed_) { 1376 if (FLAGS_check_peer_address_change_after_decryption) {
1366 SendConnectionCloseWithDetails(QUIC_ERROR_MIGRATING_ADDRESS, 1377 if (IsInitializedIPEndPoint(self_address_) &&
1367 "Self address migration is not supported."); 1378 IsInitializedIPEndPoint(last_packet_destination_address_) &&
1368 return false; 1379 (!(self_address_ == last_packet_destination_address_))) {
1380 SendConnectionCloseWithDetails(
1381 QUIC_ERROR_MIGRATING_ADDRESS,
1382 "Self address migration is not supported.");
1383 return false;
1384 }
1385 } else {
1386 if (self_ip_changed_ || self_port_changed_) {
1387 SendConnectionCloseWithDetails(
1388 QUIC_ERROR_MIGRATING_ADDRESS,
1389 "Self address migration is not supported.");
1390 return false;
1391 }
1369 } 1392 }
1370 1393
1371 if (!Near(header.packet_number, last_header_.packet_number)) { 1394 if (!Near(header.packet_number, last_header_.packet_number)) {
1372 DVLOG(1) << ENDPOINT << "Packet " << header.packet_number 1395 DVLOG(1) << ENDPOINT << "Packet " << header.packet_number
1373 << " out of bounds. Discarding"; 1396 << " out of bounds. Discarding";
1374 SendConnectionCloseWithDetails(QUIC_INVALID_PACKET_HEADER, 1397 SendConnectionCloseWithDetails(QUIC_INVALID_PACKET_HEADER,
1375 "packet number out of bounds"); 1398 "packet number out of bounds");
1376 return false; 1399 return false;
1377 } 1400 }
1378 1401
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1414 version_negotiation_state_ = NEGOTIATED_VERSION; 1437 version_negotiation_state_ = NEGOTIATED_VERSION;
1415 visitor_->OnSuccessfulVersionNegotiation(version()); 1438 visitor_->OnSuccessfulVersionNegotiation(version());
1416 if (debug_visitor_ != nullptr) { 1439 if (debug_visitor_ != nullptr) {
1417 debug_visitor_->OnSuccessfulVersionNegotiation(version()); 1440 debug_visitor_->OnSuccessfulVersionNegotiation(version());
1418 } 1441 }
1419 } 1442 }
1420 } 1443 }
1421 1444
1422 DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_); 1445 DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_);
1423 1446
1424 if (peer_ip_changed_ || peer_port_changed_) {
1425 PeerAddressChangeType type = DeterminePeerAddressChangeType();
1426 IPEndPoint old_peer_address = peer_address_;
1427 peer_address_ = IPEndPoint(
1428 peer_ip_changed_ ? migrating_peer_ip_ : peer_address_.address().bytes(),
1429 peer_port_changed_ ? migrating_peer_port_ : peer_address_.port());
1430
1431 DVLOG(1) << ENDPOINT << "Peer's ip:port changed from "
1432 << old_peer_address.ToString() << " to "
1433 << peer_address_.ToString() << ", migrating connection.";
1434
1435 visitor_->OnConnectionMigration();
1436 DCHECK_NE(type, NO_CHANGE);
1437 sent_packet_manager_.OnConnectionMigration(type);
1438 }
1439
1440 time_of_last_received_packet_ = clock_->Now(); 1447 time_of_last_received_packet_ = clock_->Now();
1441 DVLOG(1) << ENDPOINT << "time of last received packet: " 1448 DVLOG(1) << ENDPOINT << "time of last received packet: "
1442 << time_of_last_received_packet_.ToDebuggingValue(); 1449 << time_of_last_received_packet_.ToDebuggingValue();
1443 1450
1444 if (last_size_ > largest_received_packet_size_) { 1451 if (last_size_ > largest_received_packet_size_) {
1445 largest_received_packet_size_ = last_size_; 1452 largest_received_packet_size_ = last_size_;
1446 } 1453 }
1447 1454
1448 if (perspective_ == Perspective::IS_SERVER && 1455 if (perspective_ == Perspective::IS_SERVER &&
1449 encryption_level_ == ENCRYPTION_NONE && 1456 encryption_level_ == ENCRYPTION_NONE &&
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
1831 // If a forward-secure encrypter is available but is not being used and the 1838 // If a forward-secure encrypter is available but is not being used and the
1832 // next packet number is the first packet which requires 1839 // next packet number is the first packet which requires
1833 // forward security, start using the forward-secure encrypter. 1840 // forward security, start using the forward-secure encrypter.
1834 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE && 1841 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE &&
1835 has_forward_secure_encrypter_ && 1842 has_forward_secure_encrypter_ &&
1836 packet->packet_number >= first_required_forward_secure_packet_ - 1) { 1843 packet->packet_number >= first_required_forward_secure_packet_ - 1) {
1837 SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); 1844 SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
1838 } 1845 }
1839 } 1846 }
1840 1847
1841 PeerAddressChangeType QuicConnection::DeterminePeerAddressChangeType() {
1842 return UNSPECIFIED_CHANGE;
1843 }
1844
1845 void QuicConnection::OnPingTimeout() { 1848 void QuicConnection::OnPingTimeout() {
1846 if (!retransmission_alarm_->IsSet()) { 1849 if (!retransmission_alarm_->IsSet()) {
1847 SendPing(); 1850 SendPing();
1848 } 1851 }
1849 } 1852 }
1850 1853
1851 void QuicConnection::SendPing() { 1854 void QuicConnection::SendPing() {
1852 ScopedPacketBundler bundler(this, ack_queued_ ? SEND_ACK : NO_ACK); 1855 ScopedPacketBundler bundler(this, ack_queued_ ? SEND_ACK : NO_ACK);
1853 packet_generator_.AddControlFrame(QuicFrame(QuicPingFrame())); 1856 packet_generator_.AddControlFrame(QuicFrame(QuicPingFrame()));
1854 // Send PING frame immediately, without checking for congestion window bounds. 1857 // Send PING frame immediately, without checking for congestion window bounds.
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
2439 next_mtu_probe_at_ = 2442 next_mtu_probe_at_ =
2440 packet_number_of_last_sent_packet_ + packets_between_mtu_probes_ + 1; 2443 packet_number_of_last_sent_packet_ + packets_between_mtu_probes_ + 1;
2441 ++mtu_probe_count_; 2444 ++mtu_probe_count_;
2442 2445
2443 DVLOG(2) << "Sending a path MTU discovery packet #" << mtu_probe_count_; 2446 DVLOG(2) << "Sending a path MTU discovery packet #" << mtu_probe_count_;
2444 SendMtuDiscoveryPacket(mtu_discovery_target_); 2447 SendMtuDiscoveryPacket(mtu_discovery_target_);
2445 2448
2446 DCHECK(!mtu_discovery_alarm_->IsSet()); 2449 DCHECK(!mtu_discovery_alarm_->IsSet());
2447 } 2450 }
2448 2451
2452 PeerAddressChangeType QuicConnection::DeterminePeerAddressChangeType() {
2453 IPEndPoint last_peer_address;
2454 if (FLAGS_check_peer_address_change_after_decryption) {
2455 last_peer_address = last_packet_source_address_;
2456 } else {
2457 last_peer_address = IPEndPoint(
2458 peer_ip_changed_ ? migrating_peer_ip_ : peer_address_.address().bytes(),
2459 peer_port_changed_ ? migrating_peer_port_ : peer_address_.port());
2460 }
2461
2462 if (!IsInitializedIPEndPoint(peer_address_) ||
2463 !IsInitializedIPEndPoint(last_peer_address) ||
2464 peer_address_ == last_peer_address) {
2465 return NO_CHANGE;
2466 }
2467
2468 if (peer_address_.address() == last_peer_address.address()) {
2469 return PORT_CHANGE;
2470 }
2471
2472 bool old_ip_is_ipv4 = peer_address_.address().IsIPv4();
2473 bool migrating_ip_is_ipv4 = last_peer_address.address().IsIPv4();
2474 if (old_ip_is_ipv4 && !migrating_ip_is_ipv4) {
2475 return IPV4_TO_IPV6_CHANGE;
2476 }
2477
2478 if (!old_ip_is_ipv4) {
2479 return migrating_ip_is_ipv4 ? IPV6_TO_IPV4_CHANGE : IPV6_TO_IPV6_CHANGE;
2480 }
2481
2482 // TODO(rtenneti): Implement better way to test SubnetMask length of 24 bits.
2483 IPAddressNumber peer_address_bytes = peer_address_.address().bytes();
2484 IPAddressNumber last_peer_address_bytes = last_peer_address.address().bytes();
2485 if (peer_address_bytes[0] == last_peer_address_bytes[0] &&
2486 peer_address_bytes[1] == last_peer_address_bytes[1] &&
2487 peer_address_bytes[2] == last_peer_address_bytes[2]) {
2488 // Subnet part does not change (here, we use /24), which is considered to be
2489 // caused by NATs.
2490 return IPV4_SUBNET_CHANGE;
2491 }
2492
2493 return UNSPECIFIED_CHANGE;
2494 }
2495
2496 void QuicConnection::MaybeMigrateConnectionToNewPeerAddress() {
2497 PeerAddressChangeType peer_address_change_type =
2498 DeterminePeerAddressChangeType();
2499 // TODO(fayang): Currently, all peer address change type are allowed. Need to
2500 // add a method ShouldAllowPeerAddressChange(PeerAddressChangeType type) to
2501 // determine whehter |type| is allowed.
2502 if (FLAGS_check_peer_address_change_after_decryption) {
2503 if (peer_address_change_type == NO_CHANGE) {
2504 return;
2505 }
2506
2507 IPEndPoint old_peer_address = peer_address_;
2508 peer_address_ = last_packet_source_address_;
2509
2510 DVLOG(1) << ENDPOINT << "Peer's ip:port changed from "
2511 << old_peer_address.ToString() << " to "
2512 << peer_address_.ToString() << ", migrating connection.";
2513
2514 visitor_->OnConnectionMigration();
2515 sent_packet_manager_.OnConnectionMigration(peer_address_change_type);
2516
2517 return;
2518 }
2519
2520 if (peer_ip_changed_ || peer_port_changed_) {
2521 IPEndPoint old_peer_address = peer_address_;
2522 peer_address_ = IPEndPoint(
2523 peer_ip_changed_ ? migrating_peer_ip_ : peer_address_.address().bytes(),
2524 peer_port_changed_ ? migrating_peer_port_ : peer_address_.port());
2525
2526 DVLOG(1) << ENDPOINT << "Peer's ip:port changed from "
2527 << old_peer_address.ToString() << " to "
2528 << peer_address_.ToString() << ", migrating connection.";
2529
2530 visitor_->OnConnectionMigration();
2531 DCHECK_NE(peer_address_change_type, NO_CHANGE);
2532 sent_packet_manager_.OnConnectionMigration(peer_address_change_type);
2533 }
2534 }
2535
2449 void QuicConnection::OnPathClosed(QuicPathId path_id) { 2536 void QuicConnection::OnPathClosed(QuicPathId path_id) {
2450 // Stop receiving packets on this path. 2537 // Stop receiving packets on this path.
2451 framer_.OnPathClosed(path_id); 2538 framer_.OnPathClosed(path_id);
2452 } 2539 }
2453 2540
2454 bool QuicConnection::ack_frame_updated() const { 2541 bool QuicConnection::ack_frame_updated() const {
2455 return received_packet_manager_.ack_frame_updated(); 2542 return received_packet_manager_.ack_frame_updated();
2456 } 2543 }
2457 2544
2458 } // namespace net 2545 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_flags.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698