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

Unified Diff: net/quic/quic_connection.cc

Issue 1660593004: Landing Recent QUIC changes until 01/28/2016 18:41 UTC (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@Final_0202
Patch Set: Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/quic_connection.cc
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index 25cc949158a584dc9f6d80fbf0b040c7c66eb53f..6c6a1f27757805f2ee97a6f632e77c07c2fb4881 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -21,6 +21,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
+#include "net/base/address_family.h"
#include "net/base/net_errors.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/crypto/quic_decrypter.h"
@@ -79,6 +80,11 @@ bool Near(QuicPacketNumber a, QuicPacketNumber b) {
return delta <= kMaxPacketGap;
}
+bool IsInitializedIPEndPoint(const IPEndPoint& address) {
+ return net::GetAddressFamily(address.address().bytes()) !=
+ net::ADDRESS_FAMILY_UNSPECIFIED;
+}
+
// An alarm that is scheduled to send an ack if a timeout occurs.
class AckAlarm : public QuicAlarm::Delegate {
public:
@@ -665,6 +671,8 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
return false;
}
+ MaybeMigrateConnectionToNewPeerAddress();
+
--stats_.packets_dropped;
DVLOG(1) << ENDPOINT << "Received packet header: " << header;
last_header_ = header;
@@ -1188,8 +1196,8 @@ void QuicConnection::SendRstStream(QuicStreamId id,
QueuedPacketList::iterator packet_iterator = queued_packets_.begin();
while (packet_iterator != queued_packets_.end()) {
QuicFrames* retransmittable_frames =
- packet_iterator->retransmittable_frames;
- if (retransmittable_frames == nullptr) {
+ &packet_iterator->retransmittable_frames;
+ if (retransmittable_frames->empty()) {
++packet_iterator;
continue;
}
@@ -1259,7 +1267,18 @@ void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address,
}
last_size_ = packet.length();
- CheckForAddressMigration(self_address, peer_address);
+ if (FLAGS_check_peer_address_change_after_decryption) {
+ last_packet_destination_address_ = self_address;
+ last_packet_source_address_ = peer_address;
+ if (!IsInitializedIPEndPoint(self_address_)) {
+ self_address_ = last_packet_destination_address_;
+ }
+ if (!IsInitializedIPEndPoint(peer_address_)) {
+ peer_address_ = last_packet_source_address_;
+ }
+ } else {
+ CheckForAddressMigration(self_address, peer_address);
+ }
stats_.bytes_received += packet.length();
++stats_.packets_received;
@@ -1314,14 +1333,6 @@ void QuicConnection::CheckForAddressMigration(const IPEndPoint& self_address,
self_ip_changed_ = (self_address.address() != self_address_.address());
self_port_changed_ = (self_address.port() != self_address_.port());
}
-
- // TODO(vasilvv): reset maximum packet size on connection migration. Whenever
- // the connection is migrated, it usually ends up being on a different path,
- // with possibly smaller MTU. This means the max packet size has to be reset
- // and MTU discovery mechanism re-initialized. The main reason the code does
- // not do it now is that the retransmission code currently cannot deal with
- // the case when it needs to resend a packet created with larger MTU (see
- // b/22172803).
}
void QuicConnection::OnCanWrite() {
@@ -1362,10 +1373,22 @@ void QuicConnection::WriteIfNotBlocked() {
}
bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
- if (self_ip_changed_ || self_port_changed_) {
- SendConnectionCloseWithDetails(QUIC_ERROR_MIGRATING_ADDRESS,
- "Self address migration is not supported.");
- return false;
+ if (FLAGS_check_peer_address_change_after_decryption) {
+ if (IsInitializedIPEndPoint(self_address_) &&
+ IsInitializedIPEndPoint(last_packet_destination_address_) &&
+ (!(self_address_ == last_packet_destination_address_))) {
+ SendConnectionCloseWithDetails(
+ QUIC_ERROR_MIGRATING_ADDRESS,
+ "Self address migration is not supported.");
+ return false;
+ }
+ } else {
+ if (self_ip_changed_ || self_port_changed_) {
+ SendConnectionCloseWithDetails(
+ QUIC_ERROR_MIGRATING_ADDRESS,
+ "Self address migration is not supported.");
+ return false;
+ }
}
if (!Near(header.packet_number, last_header_.packet_number)) {
@@ -1421,22 +1444,6 @@ bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_);
- if (peer_ip_changed_ || peer_port_changed_) {
- PeerAddressChangeType type = DeterminePeerAddressChangeType();
- IPEndPoint old_peer_address = peer_address_;
- peer_address_ = IPEndPoint(
- peer_ip_changed_ ? migrating_peer_ip_ : peer_address_.address().bytes(),
- peer_port_changed_ ? migrating_peer_port_ : peer_address_.port());
-
- DVLOG(1) << ENDPOINT << "Peer's ip:port changed from "
- << old_peer_address.ToString() << " to "
- << peer_address_.ToString() << ", migrating connection.";
-
- visitor_->OnConnectionMigration();
- DCHECK_NE(type, NO_CHANGE);
- sent_packet_manager_.OnConnectionMigration(type);
- }
-
time_of_last_received_packet_ = clock_->Now();
DVLOG(1) << ENDPOINT << "time of last received packet: "
<< time_of_last_received_packet_.ToDebuggingValue();
@@ -1825,6 +1832,7 @@ void QuicConnection::SendOrQueuePacket(SerializedPacket* packet) {
packet->packet = packet->packet->Clone();
}
queued_packets_.push_back(*packet);
+ packet->retransmittable_frames.clear();
}
// If a forward-secure encrypter is available but is not being used and the
@@ -1837,10 +1845,6 @@ void QuicConnection::SendOrQueuePacket(SerializedPacket* packet) {
}
}
-PeerAddressChangeType QuicConnection::DeterminePeerAddressChangeType() {
- return UNSPECIFIED_CHANGE;
-}
-
void QuicConnection::OnPingTimeout() {
if (!retransmission_alarm_->IsSet()) {
SendPing();
@@ -2359,7 +2363,7 @@ HasRetransmittableData QuicConnection::IsRetransmittable(
// Retransmitted packets retransmittable frames are owned by the unacked
// packet map, but are not present in the serialized packet.
if (packet.transmission_type != NOT_RETRANSMISSION ||
- packet.retransmittable_frames != nullptr) {
+ !packet.retransmittable_frames.empty()) {
return HAS_RETRANSMITTABLE_DATA;
} else {
return NO_RETRANSMITTABLE_DATA;
@@ -2367,10 +2371,10 @@ HasRetransmittableData QuicConnection::IsRetransmittable(
}
bool QuicConnection::IsTerminationPacket(const SerializedPacket& packet) {
- if (packet.retransmittable_frames == nullptr) {
+ if (packet.retransmittable_frames.empty()) {
return false;
}
- for (const QuicFrame& frame : *packet.retransmittable_frames) {
+ for (const QuicFrame& frame : packet.retransmittable_frames) {
if (frame.type == CONNECTION_CLOSE_FRAME) {
return true;
}
@@ -2445,6 +2449,90 @@ void QuicConnection::DiscoverMtu() {
DCHECK(!mtu_discovery_alarm_->IsSet());
}
+PeerAddressChangeType QuicConnection::DeterminePeerAddressChangeType() {
+ IPEndPoint last_peer_address;
+ if (FLAGS_check_peer_address_change_after_decryption) {
+ last_peer_address = last_packet_source_address_;
+ } else {
+ last_peer_address = IPEndPoint(
+ peer_ip_changed_ ? migrating_peer_ip_ : peer_address_.address().bytes(),
+ peer_port_changed_ ? migrating_peer_port_ : peer_address_.port());
+ }
+
+ if (!IsInitializedIPEndPoint(peer_address_) ||
+ !IsInitializedIPEndPoint(last_peer_address) ||
+ peer_address_ == last_peer_address) {
+ return NO_CHANGE;
+ }
+
+ if (peer_address_.address() == last_peer_address.address()) {
+ return PORT_CHANGE;
+ }
+
+ bool old_ip_is_ipv4 = peer_address_.address().IsIPv4();
+ bool migrating_ip_is_ipv4 = last_peer_address.address().IsIPv4();
+ if (old_ip_is_ipv4 && !migrating_ip_is_ipv4) {
+ return IPV4_TO_IPV6_CHANGE;
+ }
+
+ if (!old_ip_is_ipv4) {
+ return migrating_ip_is_ipv4 ? IPV6_TO_IPV4_CHANGE : IPV6_TO_IPV6_CHANGE;
+ }
+
+ // TODO(rtenneti): Implement better way to test SubnetMask length of 24 bits.
+ IPAddressNumber peer_address_bytes = peer_address_.address().bytes();
+ IPAddressNumber last_peer_address_bytes = last_peer_address.address().bytes();
+ if (peer_address_bytes[0] == last_peer_address_bytes[0] &&
+ peer_address_bytes[1] == last_peer_address_bytes[1] &&
+ peer_address_bytes[2] == last_peer_address_bytes[2]) {
+ // Subnet part does not change (here, we use /24), which is considered to be
+ // caused by NATs.
+ return IPV4_SUBNET_CHANGE;
+ }
+
+ return UNSPECIFIED_CHANGE;
+}
+
+void QuicConnection::MaybeMigrateConnectionToNewPeerAddress() {
+ PeerAddressChangeType peer_address_change_type =
+ DeterminePeerAddressChangeType();
+ // TODO(fayang): Currently, all peer address change type are allowed. Need to
+ // add a method ShouldAllowPeerAddressChange(PeerAddressChangeType type) to
+ // determine whehter |type| is allowed.
+ if (FLAGS_check_peer_address_change_after_decryption) {
+ if (peer_address_change_type == NO_CHANGE) {
+ return;
+ }
+
+ IPEndPoint old_peer_address = peer_address_;
+ peer_address_ = last_packet_source_address_;
+
+ DVLOG(1) << ENDPOINT << "Peer's ip:port changed from "
+ << old_peer_address.ToString() << " to "
+ << peer_address_.ToString() << ", migrating connection.";
+
+ visitor_->OnConnectionMigration();
+ sent_packet_manager_.OnConnectionMigration(peer_address_change_type);
+
+ return;
+ }
+
+ if (peer_ip_changed_ || peer_port_changed_) {
+ IPEndPoint old_peer_address = peer_address_;
+ peer_address_ = IPEndPoint(
+ peer_ip_changed_ ? migrating_peer_ip_ : peer_address_.address().bytes(),
+ peer_port_changed_ ? migrating_peer_port_ : peer_address_.port());
+
+ DVLOG(1) << ENDPOINT << "Peer's ip:port changed from "
+ << old_peer_address.ToString() << " to "
+ << peer_address_.ToString() << ", migrating connection.";
+
+ visitor_->OnConnectionMigration();
+ DCHECK_NE(peer_address_change_type, NO_CHANGE);
+ sent_packet_manager_.OnConnectionMigration(peer_address_change_type);
+ }
+}
+
void QuicConnection::OnPathClosed(QuicPathId path_id) {
// Stop receiving packets on this path.
framer_.OnPathClosed(path_id);
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698