| Index: net/quic/quic_connection.cc
|
| diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
|
| index 1bfc6ff5211c823369c8120d1d0449a75196f889..a5469596a32ad8b07c9eb5ccfd61f0fe9f061d4d 100644
|
| --- a/net/quic/quic_connection.cc
|
| +++ b/net/quic/quic_connection.cc
|
| @@ -207,7 +207,7 @@ class MtuDiscoveryAckListener : public QuicAckNotifier::DelegateInterface {
|
| QuicTime::Delta /*delta_largest_observed*/) override {
|
| // Since the probe was successful, increase the maximum packet size to that.
|
| if (probe_size_ > connection_->max_packet_length()) {
|
| - connection_->set_max_packet_length(probe_size_);
|
| + connection_->SetMaxPacketLength(probe_size_);
|
| }
|
| }
|
|
|
| @@ -327,9 +327,11 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id,
|
| framer_.set_received_entropy_calculator(&received_packet_manager_);
|
| stats_.connection_creation_time = clock_->ApproximateNow();
|
| sent_packet_manager_.set_network_change_visitor(this);
|
| - if (perspective_ == Perspective::IS_SERVER) {
|
| - set_max_packet_length(kDefaultServerMaxPacketSize);
|
| - }
|
| + // Allow the packet writer to potentially reduce the packet size to a value
|
| + // even smaller than kDefaultMaxPacketSize.
|
| + SetMaxPacketLength(perspective_ == Perspective::IS_SERVER
|
| + ? kDefaultServerMaxPacketSize
|
| + : kDefaultMaxPacketSize);
|
| }
|
|
|
| QuicConnection::~QuicConnection() {
|
| @@ -381,10 +383,10 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
|
| }
|
|
|
| if (config.HasClientSentConnectionOption(kMTUH, perspective_)) {
|
| - mtu_discovery_target_ = kMtuDiscoveryTargetPacketSizeHigh;
|
| + SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh);
|
| }
|
| if (config.HasClientSentConnectionOption(kMTUL, perspective_)) {
|
| - mtu_discovery_target_ = kMtuDiscoveryTargetPacketSizeLow;
|
| + SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeLow);
|
| }
|
| }
|
|
|
| @@ -746,8 +748,8 @@ bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) {
|
| if (incoming_ack.is_truncated) {
|
| should_last_packet_instigate_acks_ = true;
|
| }
|
| - if (!incoming_ack.missing_packets.empty() &&
|
| - GetLeastUnacked() > *incoming_ack.missing_packets.begin()) {
|
| + if (!incoming_ack.missing_packets.Empty() &&
|
| + GetLeastUnacked() > incoming_ack.missing_packets.Min()) {
|
| ++stop_waiting_count_;
|
| } else {
|
| stop_waiting_count_ = 0;
|
| @@ -831,20 +833,20 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
|
| return false;
|
| }
|
|
|
| - if (!incoming_ack.missing_packets.empty() &&
|
| - *incoming_ack.missing_packets.rbegin() > incoming_ack.largest_observed) {
|
| + if (!incoming_ack.missing_packets.Empty() &&
|
| + incoming_ack.missing_packets.Max() > incoming_ack.largest_observed) {
|
| DLOG(ERROR) << ENDPOINT << "Peer sent missing packet: "
|
| - << *incoming_ack.missing_packets.rbegin()
|
| + << incoming_ack.missing_packets.Max()
|
| << " which is greater than largest observed: "
|
| << incoming_ack.largest_observed;
|
| return false;
|
| }
|
|
|
| - if (!incoming_ack.missing_packets.empty() &&
|
| - *incoming_ack.missing_packets.begin() <
|
| + if (!incoming_ack.missing_packets.Empty() &&
|
| + incoming_ack.missing_packets.Min() <
|
| sent_packet_manager_.least_packet_awaited_by_peer()) {
|
| DLOG(ERROR) << ENDPOINT << "Peer sent missing packet: "
|
| - << *incoming_ack.missing_packets.begin()
|
| + << incoming_ack.missing_packets.Min()
|
| << " which is smaller than least_packet_awaited_by_peer_: "
|
| << sent_packet_manager_.least_packet_awaited_by_peer();
|
| return false;
|
| @@ -859,7 +861,7 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
|
| }
|
|
|
| for (QuicPacketNumber revived_packet : incoming_ack.revived_packets) {
|
| - if (!ContainsKey(incoming_ack.missing_packets, revived_packet)) {
|
| + if (!incoming_ack.missing_packets.Contains(revived_packet)) {
|
| DLOG(ERROR) << ENDPOINT
|
| << "Peer specified revived packet which was not missing.";
|
| return false;
|
| @@ -905,7 +907,9 @@ bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
|
| if (debug_visitor_ != nullptr) {
|
| debug_visitor_->OnRstStreamFrame(frame);
|
| }
|
| - DVLOG(1) << ENDPOINT << "Stream reset with error "
|
| + DVLOG(1) << ENDPOINT
|
| + << "RST_STREAM_FRAME received for stream: " << frame.stream_id
|
| + << " with error: "
|
| << QuicUtils::StreamErrorToString(frame.error_code);
|
| if (FLAGS_quic_process_frames_inline) {
|
| visitor_->OnRstStream(frame);
|
| @@ -922,9 +926,9 @@ bool QuicConnection::OnConnectionCloseFrame(
|
| if (debug_visitor_ != nullptr) {
|
| debug_visitor_->OnConnectionCloseFrame(frame);
|
| }
|
| - DVLOG(1) << ENDPOINT << "Connection " << connection_id()
|
| - << " closed with error "
|
| - << QuicUtils::ErrorToString(frame.error_code)
|
| + DVLOG(1) << ENDPOINT << "CONNECTION_CLOSE_FRAME received for connection: "
|
| + << connection_id()
|
| + << " with error: " << QuicUtils::ErrorToString(frame.error_code)
|
| << " " << frame.error_details;
|
| if (FLAGS_quic_process_frames_inline) {
|
| CloseConnection(frame.error_code, true);
|
| @@ -939,9 +943,10 @@ bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
|
| if (debug_visitor_ != nullptr) {
|
| debug_visitor_->OnGoAwayFrame(frame);
|
| }
|
| - DVLOG(1) << ENDPOINT << "Go away received with error "
|
| - << QuicUtils::ErrorToString(frame.error_code)
|
| - << " and reason:" << frame.reason_phrase;
|
| + DVLOG(1) << ENDPOINT << "GOAWAY_FRAME received with last good stream: "
|
| + << frame.last_good_stream_id
|
| + << " and error: " << QuicUtils::ErrorToString(frame.error_code)
|
| + << " and reason: " << frame.reason_phrase;
|
|
|
| goaway_received_ = true;
|
| if (FLAGS_quic_process_frames_inline) {
|
| @@ -958,8 +963,9 @@ bool QuicConnection::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
|
| if (debug_visitor_ != nullptr) {
|
| debug_visitor_->OnWindowUpdateFrame(frame);
|
| }
|
| - DVLOG(1) << ENDPOINT << "WindowUpdate received for stream: "
|
| - << frame.stream_id << " with byte offset: " << frame.byte_offset;
|
| + DVLOG(1) << ENDPOINT
|
| + << "WINDOW_UPDATE_FRAME received for stream: " << frame.stream_id
|
| + << " with byte offset: " << frame.byte_offset;
|
| if (FLAGS_quic_process_frames_inline) {
|
| visitor_->OnWindowUpdateFrame(frame);
|
| should_last_packet_instigate_acks_ = true;
|
| @@ -974,8 +980,8 @@ bool QuicConnection::OnBlockedFrame(const QuicBlockedFrame& frame) {
|
| if (debug_visitor_ != nullptr) {
|
| debug_visitor_->OnBlockedFrame(frame);
|
| }
|
| - DVLOG(1) << ENDPOINT << "Blocked frame received for stream: "
|
| - << frame.stream_id;
|
| + DVLOG(1) << ENDPOINT
|
| + << "BLOCKED_FRAME received for stream: " << frame.stream_id;
|
| if (FLAGS_quic_process_frames_inline) {
|
| visitor_->OnBlockedFrame(frame);
|
| should_last_packet_instigate_acks_ = true;
|
| @@ -1191,8 +1197,8 @@ void QuicConnection::UpdateStopWaitingCount() {
|
|
|
| // If the peer is still waiting for a packet that we are no longer planning to
|
| // send, send an ack to raise the high water mark.
|
| - if (!last_ack_frames_.back().missing_packets.empty() &&
|
| - GetLeastUnacked() > *last_ack_frames_.back().missing_packets.begin()) {
|
| + if (!last_ack_frames_.back().missing_packets.Empty() &&
|
| + GetLeastUnacked() > last_ack_frames_.back().missing_packets.Min()) {
|
| ++stop_waiting_count_;
|
| } else {
|
| stop_waiting_count_ = 0;
|
| @@ -1417,6 +1423,14 @@ void QuicConnection::CheckForAddressMigration(
|
| 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() {
|
| @@ -1491,7 +1505,7 @@ bool QuicConnection::ProcessValidatedPacket() {
|
| if (perspective_ == Perspective::IS_SERVER &&
|
| encryption_level_ == ENCRYPTION_NONE &&
|
| last_size_ > packet_generator_.GetMaxPacketLength()) {
|
| - set_max_packet_length(last_size_);
|
| + SetMaxPacketLength(last_size_);
|
| }
|
| return true;
|
| }
|
| @@ -2143,8 +2157,9 @@ QuicByteCount QuicConnection::max_packet_length() const {
|
| return packet_generator_.GetMaxPacketLength();
|
| }
|
|
|
| -void QuicConnection::set_max_packet_length(QuicByteCount length) {
|
| - return packet_generator_.SetMaxPacketLength(length, /*force=*/false);
|
| +void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
|
| + return packet_generator_.SetMaxPacketLength(LimitMaxPacketSize(length),
|
| + /*force=*/false);
|
| }
|
|
|
| bool QuicConnection::HasQueuedData() const {
|
| @@ -2374,7 +2389,41 @@ bool QuicConnection::IsConnectionClose(const QueuedPacket& packet) {
|
| return false;
|
| }
|
|
|
| +void QuicConnection::SetMtuDiscoveryTarget(QuicByteCount target) {
|
| + mtu_discovery_target_ = LimitMaxPacketSize(target);
|
| +}
|
| +
|
| +QuicByteCount QuicConnection::LimitMaxPacketSize(
|
| + QuicByteCount suggested_max_packet_size) {
|
| + if (FLAGS_quic_allow_oversized_packets_for_test) {
|
| + return suggested_max_packet_size;
|
| + }
|
| +
|
| + if (!FLAGS_quic_limit_mtu_by_writer) {
|
| + return suggested_max_packet_size;
|
| + }
|
| +
|
| + if (peer_address_.address().empty()) {
|
| + LOG(DFATAL) << "Attempted to use a connection without a valid peer address";
|
| + return suggested_max_packet_size;
|
| + }
|
| +
|
| + const QuicByteCount writer_limit = writer_->GetMaxPacketSize(peer_address());
|
| +
|
| + QuicByteCount max_packet_size = suggested_max_packet_size;
|
| + if (max_packet_size > writer_limit) {
|
| + max_packet_size = writer_limit;
|
| + }
|
| + if (max_packet_size > kMaxPacketSize) {
|
| + max_packet_size = kMaxPacketSize;
|
| + }
|
| + return max_packet_size;
|
| +}
|
| +
|
| void QuicConnection::SendMtuDiscoveryPacket(QuicByteCount target_mtu) {
|
| + // Currently, this limit is ensured by the caller.
|
| + DCHECK_EQ(target_mtu, LimitMaxPacketSize(target_mtu));
|
| +
|
| // Create a listener for the new probe. The ownership of the listener is
|
| // transferred to the AckNotifierManager. The notifier will get destroyed
|
| // before the connection (because it's stored in one of the connection's
|
|
|