| 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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 SerializedPacket packet, | 190 SerializedPacket packet, |
| 191 EncryptionLevel level, | 191 EncryptionLevel level, |
| 192 TransmissionType transmission_type, | 192 TransmissionType transmission_type, |
| 193 QuicPacketSequenceNumber original_sequence_number) | 193 QuicPacketSequenceNumber original_sequence_number) |
| 194 : serialized_packet(packet), | 194 : serialized_packet(packet), |
| 195 encryption_level(level), | 195 encryption_level(level), |
| 196 transmission_type(transmission_type), | 196 transmission_type(transmission_type), |
| 197 original_sequence_number(original_sequence_number) { | 197 original_sequence_number(original_sequence_number) { |
| 198 } | 198 } |
| 199 | 199 |
| 200 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | 200 #define ENDPOINT \ |
| 201 (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ") |
| 201 | 202 |
| 202 QuicConnection::QuicConnection(QuicConnectionId connection_id, | 203 QuicConnection::QuicConnection(QuicConnectionId connection_id, |
| 203 IPEndPoint address, | 204 IPEndPoint address, |
| 204 QuicConnectionHelperInterface* helper, | 205 QuicConnectionHelperInterface* helper, |
| 205 const PacketWriterFactory& writer_factory, | 206 const PacketWriterFactory& writer_factory, |
| 206 bool owns_writer, | 207 bool owns_writer, |
| 207 bool is_server, | 208 Perspective perspective, |
| 208 bool is_secure, | 209 bool is_secure, |
| 209 const QuicVersionVector& supported_versions) | 210 const QuicVersionVector& supported_versions) |
| 210 : framer_(supported_versions, | 211 : framer_(supported_versions, |
| 211 helper->GetClock()->ApproximateNow(), | 212 helper->GetClock()->ApproximateNow(), |
| 212 is_server), | 213 perspective), |
| 213 helper_(helper), | 214 helper_(helper), |
| 214 writer_(writer_factory.Create(this)), | 215 writer_(writer_factory.Create(this)), |
| 215 owns_writer_(owns_writer), | 216 owns_writer_(owns_writer), |
| 216 encryption_level_(ENCRYPTION_NONE), | 217 encryption_level_(ENCRYPTION_NONE), |
| 217 has_forward_secure_encrypter_(false), | 218 has_forward_secure_encrypter_(false), |
| 218 first_required_forward_secure_packet_(0), | 219 first_required_forward_secure_packet_(0), |
| 219 clock_(helper->GetClock()), | 220 clock_(helper->GetClock()), |
| 220 random_generator_(helper->GetRandomGenerator()), | 221 random_generator_(helper->GetRandomGenerator()), |
| 221 connection_id_(connection_id), | 222 connection_id_(connection_id), |
| 222 peer_address_(address), | 223 peer_address_(address), |
| (...skipping 20 matching lines...) Expand all Loading... |
| 243 visitor_(nullptr), | 244 visitor_(nullptr), |
| 244 debug_visitor_(nullptr), | 245 debug_visitor_(nullptr), |
| 245 packet_generator_(connection_id_, &framer_, random_generator_, this), | 246 packet_generator_(connection_id_, &framer_, random_generator_, this), |
| 246 fec_alarm_(helper->CreateAlarm(new FecAlarm(&packet_generator_))), | 247 fec_alarm_(helper->CreateAlarm(new FecAlarm(&packet_generator_))), |
| 247 idle_network_timeout_(QuicTime::Delta::Infinite()), | 248 idle_network_timeout_(QuicTime::Delta::Infinite()), |
| 248 overall_connection_timeout_(QuicTime::Delta::Infinite()), | 249 overall_connection_timeout_(QuicTime::Delta::Infinite()), |
| 249 time_of_last_received_packet_(clock_->ApproximateNow()), | 250 time_of_last_received_packet_(clock_->ApproximateNow()), |
| 250 time_of_last_sent_new_packet_(clock_->ApproximateNow()), | 251 time_of_last_sent_new_packet_(clock_->ApproximateNow()), |
| 251 sequence_number_of_last_sent_packet_(0), | 252 sequence_number_of_last_sent_packet_(0), |
| 252 sent_packet_manager_( | 253 sent_packet_manager_( |
| 253 is_server, | 254 perspective, |
| 254 clock_, | 255 clock_, |
| 255 &stats_, | 256 &stats_, |
| 256 FLAGS_quic_use_bbr_congestion_control ? kBBR : kCubic, | 257 FLAGS_quic_use_bbr_congestion_control ? kBBR : kCubic, |
| 257 FLAGS_quic_use_time_loss_detection ? kTime : kNack, | 258 FLAGS_quic_use_time_loss_detection ? kTime : kNack, |
| 258 is_secure), | 259 is_secure), |
| 259 version_negotiation_state_(START_NEGOTIATION), | 260 version_negotiation_state_(START_NEGOTIATION), |
| 260 is_server_(is_server), | 261 perspective_(perspective), |
| 261 connected_(true), | 262 connected_(true), |
| 262 peer_ip_changed_(false), | 263 peer_ip_changed_(false), |
| 263 peer_port_changed_(false), | 264 peer_port_changed_(false), |
| 264 self_ip_changed_(false), | 265 self_ip_changed_(false), |
| 265 self_port_changed_(false), | 266 self_port_changed_(false), |
| 266 can_truncate_connection_ids_(true), | 267 can_truncate_connection_ids_(true), |
| 267 is_secure_(is_secure) { | 268 is_secure_(is_secure) { |
| 268 DVLOG(1) << ENDPOINT << "Created connection with connection_id: " | 269 DVLOG(1) << ENDPOINT << "Created connection with connection_id: " |
| 269 << connection_id; | 270 << connection_id; |
| 270 framer_.set_visitor(this); | 271 framer_.set_visitor(this); |
| 271 framer_.set_received_entropy_calculator(&received_packet_manager_); | 272 framer_.set_received_entropy_calculator(&received_packet_manager_); |
| 272 stats_.connection_creation_time = clock_->ApproximateNow(); | 273 stats_.connection_creation_time = clock_->ApproximateNow(); |
| 273 sent_packet_manager_.set_network_change_visitor(this); | 274 sent_packet_manager_.set_network_change_visitor(this); |
| 274 if (FLAGS_quic_small_default_packet_size && is_server_) { | 275 if (FLAGS_quic_small_default_packet_size && |
| 276 perspective_ == Perspective::IS_SERVER) { |
| 275 set_max_packet_length(kDefaultServerMaxPacketSize); | 277 set_max_packet_length(kDefaultServerMaxPacketSize); |
| 276 } | 278 } |
| 277 } | 279 } |
| 278 | 280 |
| 279 QuicConnection::~QuicConnection() { | 281 QuicConnection::~QuicConnection() { |
| 280 if (owns_writer_) { | 282 if (owns_writer_) { |
| 281 delete writer_; | 283 delete writer_; |
| 282 } | 284 } |
| 283 STLDeleteElements(&undecryptable_packets_); | 285 STLDeleteElements(&undecryptable_packets_); |
| 284 STLDeleteValues(&group_map_); | 286 STLDeleteValues(&group_map_); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 CloseConnection(QUIC_PUBLIC_RESET, true); | 381 CloseConnection(QUIC_PUBLIC_RESET, true); |
| 380 | 382 |
| 381 DVLOG(1) << ENDPOINT << "Connection " << connection_id() | 383 DVLOG(1) << ENDPOINT << "Connection " << connection_id() |
| 382 << " closed via QUIC_PUBLIC_RESET from peer."; | 384 << " closed via QUIC_PUBLIC_RESET from peer."; |
| 383 } | 385 } |
| 384 | 386 |
| 385 bool QuicConnection::OnProtocolVersionMismatch(QuicVersion received_version) { | 387 bool QuicConnection::OnProtocolVersionMismatch(QuicVersion received_version) { |
| 386 DVLOG(1) << ENDPOINT << "Received packet with mismatched version " | 388 DVLOG(1) << ENDPOINT << "Received packet with mismatched version " |
| 387 << received_version; | 389 << received_version; |
| 388 // TODO(satyamshekhar): Implement no server state in this mode. | 390 // TODO(satyamshekhar): Implement no server state in this mode. |
| 389 if (!is_server_) { | 391 if (perspective_ == Perspective::IS_CLIENT) { |
| 390 LOG(DFATAL) << ENDPOINT << "Framer called OnProtocolVersionMismatch. " | 392 LOG(DFATAL) << ENDPOINT << "Framer called OnProtocolVersionMismatch. " |
| 391 << "Closing connection."; | 393 << "Closing connection."; |
| 392 CloseConnection(QUIC_INTERNAL_ERROR, false); | 394 CloseConnection(QUIC_INTERNAL_ERROR, false); |
| 393 return false; | 395 return false; |
| 394 } | 396 } |
| 395 DCHECK_NE(version(), received_version); | 397 DCHECK_NE(version(), received_version); |
| 396 | 398 |
| 397 if (debug_visitor_ != nullptr) { | 399 if (debug_visitor_ != nullptr) { |
| 398 debug_visitor_->OnProtocolVersionMismatch(received_version); | 400 debug_visitor_->OnProtocolVersionMismatch(received_version); |
| 399 } | 401 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 | 437 |
| 436 // TODO(satyamshekhar): Store the sequence number of this packet and close the | 438 // TODO(satyamshekhar): Store the sequence number of this packet and close the |
| 437 // connection if we ever received a packet with incorrect version and whose | 439 // connection if we ever received a packet with incorrect version and whose |
| 438 // sequence number is greater. | 440 // sequence number is greater. |
| 439 return true; | 441 return true; |
| 440 } | 442 } |
| 441 | 443 |
| 442 // Handles version negotiation for client connection. | 444 // Handles version negotiation for client connection. |
| 443 void QuicConnection::OnVersionNegotiationPacket( | 445 void QuicConnection::OnVersionNegotiationPacket( |
| 444 const QuicVersionNegotiationPacket& packet) { | 446 const QuicVersionNegotiationPacket& packet) { |
| 445 if (is_server_) { | 447 if (perspective_ == Perspective::IS_SERVER) { |
| 446 LOG(DFATAL) << ENDPOINT << "Framer parsed VersionNegotiationPacket." | 448 LOG(DFATAL) << ENDPOINT << "Framer parsed VersionNegotiationPacket." |
| 447 << " Closing connection."; | 449 << " Closing connection."; |
| 448 CloseConnection(QUIC_INTERNAL_ERROR, false); | 450 CloseConnection(QUIC_INTERNAL_ERROR, false); |
| 449 return; | 451 return; |
| 450 } | 452 } |
| 451 if (debug_visitor_ != nullptr) { | 453 if (debug_visitor_ != nullptr) { |
| 452 debug_visitor_->OnVersionNegotiationPacket(packet); | 454 debug_visitor_->OnVersionNegotiationPacket(packet); |
| 453 } | 455 } |
| 454 | 456 |
| 455 if (version_negotiation_state_ != START_NEGOTIATION) { | 457 if (version_negotiation_state_ != START_NEGOTIATION) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 header.packet_sequence_number)) { | 543 header.packet_sequence_number)) { |
| 542 DVLOG(1) << ENDPOINT << "Packet " << header.packet_sequence_number | 544 DVLOG(1) << ENDPOINT << "Packet " << header.packet_sequence_number |
| 543 << " no longer being waited for. Discarding."; | 545 << " no longer being waited for. Discarding."; |
| 544 if (debug_visitor_ != nullptr) { | 546 if (debug_visitor_ != nullptr) { |
| 545 debug_visitor_->OnDuplicatePacket(header.packet_sequence_number); | 547 debug_visitor_->OnDuplicatePacket(header.packet_sequence_number); |
| 546 } | 548 } |
| 547 return false; | 549 return false; |
| 548 } | 550 } |
| 549 | 551 |
| 550 if (version_negotiation_state_ != NEGOTIATED_VERSION) { | 552 if (version_negotiation_state_ != NEGOTIATED_VERSION) { |
| 551 if (is_server_) { | 553 if (perspective_ == Perspective::IS_SERVER) { |
| 552 if (!header.public_header.version_flag) { | 554 if (!header.public_header.version_flag) { |
| 553 DLOG(WARNING) << ENDPOINT << "Packet " << header.packet_sequence_number | 555 DLOG(WARNING) << ENDPOINT << "Packet " << header.packet_sequence_number |
| 554 << " without version flag before version negotiated."; | 556 << " without version flag before version negotiated."; |
| 555 // Packets should have the version flag till version negotiation is | 557 // Packets should have the version flag till version negotiation is |
| 556 // done. | 558 // done. |
| 557 CloseConnection(QUIC_INVALID_VERSION, false); | 559 CloseConnection(QUIC_INVALID_VERSION, false); |
| 558 return false; | 560 return false; |
| 559 } else { | 561 } else { |
| 560 DCHECK_EQ(1u, header.public_header.versions.size()); | 562 DCHECK_EQ(1u, header.public_header.versions.size()); |
| 561 DCHECK_EQ(header.public_header.versions[0], version()); | 563 DCHECK_EQ(header.public_header.versions[0], version()); |
| (...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1262 DVLOG(1) << ENDPOINT << "Peer's port changed from " | 1264 DVLOG(1) << ENDPOINT << "Peer's port changed from " |
| 1263 << peer_address_.port() << " to " << migrating_peer_port_ | 1265 << peer_address_.port() << " to " << migrating_peer_port_ |
| 1264 << ", migrating connection."; | 1266 << ", migrating connection."; |
| 1265 peer_address_ = IPEndPoint(peer_address_.address(), migrating_peer_port_); | 1267 peer_address_ = IPEndPoint(peer_address_.address(), migrating_peer_port_); |
| 1266 } | 1268 } |
| 1267 | 1269 |
| 1268 time_of_last_received_packet_ = clock_->Now(); | 1270 time_of_last_received_packet_ = clock_->Now(); |
| 1269 DVLOG(1) << ENDPOINT << "time of last received packet: " | 1271 DVLOG(1) << ENDPOINT << "time of last received packet: " |
| 1270 << time_of_last_received_packet_.ToDebuggingValue(); | 1272 << time_of_last_received_packet_.ToDebuggingValue(); |
| 1271 | 1273 |
| 1272 if (is_server_ && encryption_level_ == ENCRYPTION_NONE && | 1274 if (perspective_ == Perspective::IS_SERVER && |
| 1275 encryption_level_ == ENCRYPTION_NONE && |
| 1273 last_size_ > packet_generator_.max_packet_length()) { | 1276 last_size_ > packet_generator_.max_packet_length()) { |
| 1274 set_max_packet_length(last_size_); | 1277 set_max_packet_length(last_size_); |
| 1275 } | 1278 } |
| 1276 return true; | 1279 return true; |
| 1277 } | 1280 } |
| 1278 | 1281 |
| 1279 void QuicConnection::WriteQueuedPackets() { | 1282 void QuicConnection::WriteQueuedPackets() { |
| 1280 DCHECK(!writer_->IsWriteBlocked()); | 1283 DCHECK(!writer_->IsWriteBlocked()); |
| 1281 | 1284 |
| 1282 if (pending_version_negotiation_packet_) { | 1285 if (pending_version_negotiation_packet_) { |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1589 rtt = QuicTime::Delta::FromMicroseconds( | 1592 rtt = QuicTime::Delta::FromMicroseconds( |
| 1590 sent_packet_manager_.GetRttStats()->initial_rtt_us()); | 1593 sent_packet_manager_.GetRttStats()->initial_rtt_us()); |
| 1591 } | 1594 } |
| 1592 packet_generator_.OnRttChange(rtt); | 1595 packet_generator_.OnRttChange(rtt); |
| 1593 } | 1596 } |
| 1594 | 1597 |
| 1595 void QuicConnection::OnHandshakeComplete() { | 1598 void QuicConnection::OnHandshakeComplete() { |
| 1596 sent_packet_manager_.SetHandshakeConfirmed(); | 1599 sent_packet_manager_.SetHandshakeConfirmed(); |
| 1597 // The client should immediately ack the SHLO to confirm the handshake is | 1600 // The client should immediately ack the SHLO to confirm the handshake is |
| 1598 // complete with the server. | 1601 // complete with the server. |
| 1599 if (!is_server_ && !ack_queued_) { | 1602 if (perspective_ == Perspective::IS_CLIENT && !ack_queued_) { |
| 1600 ack_alarm_->Cancel(); | 1603 ack_alarm_->Cancel(); |
| 1601 ack_alarm_->Set(clock_->ApproximateNow()); | 1604 ack_alarm_->Set(clock_->ApproximateNow()); |
| 1602 } | 1605 } |
| 1603 } | 1606 } |
| 1604 | 1607 |
| 1605 void QuicConnection::SendOrQueuePacket(QueuedPacket packet) { | 1608 void QuicConnection::SendOrQueuePacket(QueuedPacket packet) { |
| 1606 // The caller of this function is responsible for checking CanWrite(). | 1609 // The caller of this function is responsible for checking CanWrite(). |
| 1607 if (packet.serialized_packet.packet == nullptr) { | 1610 if (packet.serialized_packet.packet == nullptr) { |
| 1608 LOG(DFATAL) | 1611 LOG(DFATAL) |
| 1609 << "packet.serialized_packet.packet == nullptr in to SendOrQueuePacket"; | 1612 << "packet.serialized_packet.packet == nullptr in to SendOrQueuePacket"; |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1935 pending_handshake); | 1938 pending_handshake); |
| 1936 } | 1939 } |
| 1937 | 1940 |
| 1938 void QuicConnection::SetNetworkTimeouts(QuicTime::Delta overall_timeout, | 1941 void QuicConnection::SetNetworkTimeouts(QuicTime::Delta overall_timeout, |
| 1939 QuicTime::Delta idle_timeout) { | 1942 QuicTime::Delta idle_timeout) { |
| 1940 LOG_IF(DFATAL, idle_timeout > overall_timeout) | 1943 LOG_IF(DFATAL, idle_timeout > overall_timeout) |
| 1941 << "idle_timeout:" << idle_timeout.ToMilliseconds() | 1944 << "idle_timeout:" << idle_timeout.ToMilliseconds() |
| 1942 << " overall_timeout:" << overall_timeout.ToMilliseconds(); | 1945 << " overall_timeout:" << overall_timeout.ToMilliseconds(); |
| 1943 // Adjust the idle timeout on client and server to prevent clients from | 1946 // Adjust the idle timeout on client and server to prevent clients from |
| 1944 // sending requests to servers which have already closed the connection. | 1947 // sending requests to servers which have already closed the connection. |
| 1945 if (is_server_) { | 1948 if (perspective_ == Perspective::IS_SERVER) { |
| 1946 idle_timeout = idle_timeout.Add(QuicTime::Delta::FromSeconds(3)); | 1949 idle_timeout = idle_timeout.Add(QuicTime::Delta::FromSeconds(3)); |
| 1947 } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) { | 1950 } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) { |
| 1948 idle_timeout = idle_timeout.Subtract(QuicTime::Delta::FromSeconds(1)); | 1951 idle_timeout = idle_timeout.Subtract(QuicTime::Delta::FromSeconds(1)); |
| 1949 } | 1952 } |
| 1950 overall_connection_timeout_ = overall_timeout; | 1953 overall_connection_timeout_ = overall_timeout; |
| 1951 idle_network_timeout_ = idle_timeout; | 1954 idle_network_timeout_ = idle_timeout; |
| 1952 | 1955 |
| 1953 SetTimeoutAlarm(); | 1956 SetTimeoutAlarm(); |
| 1954 } | 1957 } |
| 1955 | 1958 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2000 deadline = min(deadline, | 2003 deadline = min(deadline, |
| 2001 stats_.connection_creation_time.Add( | 2004 stats_.connection_creation_time.Add( |
| 2002 overall_connection_timeout_)); | 2005 overall_connection_timeout_)); |
| 2003 } | 2006 } |
| 2004 | 2007 |
| 2005 timeout_alarm_->Cancel(); | 2008 timeout_alarm_->Cancel(); |
| 2006 timeout_alarm_->Set(deadline); | 2009 timeout_alarm_->Set(deadline); |
| 2007 } | 2010 } |
| 2008 | 2011 |
| 2009 void QuicConnection::SetPingAlarm() { | 2012 void QuicConnection::SetPingAlarm() { |
| 2010 if (is_server_) { | 2013 if (perspective_ == Perspective::IS_SERVER) { |
| 2011 // Only clients send pings. | 2014 // Only clients send pings. |
| 2012 return; | 2015 return; |
| 2013 } | 2016 } |
| 2014 if (!visitor_->HasOpenDataStreams()) { | 2017 if (!visitor_->HasOpenDataStreams()) { |
| 2015 ping_alarm_->Cancel(); | 2018 ping_alarm_->Cancel(); |
| 2016 // Don't send a ping unless there are open streams. | 2019 // Don't send a ping unless there are open streams. |
| 2017 return; | 2020 return; |
| 2018 } | 2021 } |
| 2019 QuicTime::Delta ping_timeout = QuicTime::Delta::FromSeconds(kPingTimeoutSecs); | 2022 QuicTime::Delta ping_timeout = QuicTime::Delta::FromSeconds(kPingTimeoutSecs); |
| 2020 ping_alarm_->Update(clock_->ApproximateNow().Add(ping_timeout), | 2023 ping_alarm_->Update(clock_->ApproximateNow().Add(ping_timeout), |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2079 } | 2082 } |
| 2080 for (const QuicFrame& frame : retransmittable_frames->frames()) { | 2083 for (const QuicFrame& frame : retransmittable_frames->frames()) { |
| 2081 if (frame.type == CONNECTION_CLOSE_FRAME) { | 2084 if (frame.type == CONNECTION_CLOSE_FRAME) { |
| 2082 return true; | 2085 return true; |
| 2083 } | 2086 } |
| 2084 } | 2087 } |
| 2085 return false; | 2088 return false; |
| 2086 } | 2089 } |
| 2087 | 2090 |
| 2088 } // namespace net | 2091 } // namespace net |
| OLD | NEW |