src/net/third_party/quiche/src/quic/core/quic_connection_test.cc
// Tests whether MTU discovery works when all probes are acknowledged on the
// first try.
Tests whether MTU discovery works when all probes are acknowledged on the
first try.
Tests whether MTU discovery works when all probes are acknowledged on the first try .
TEST_P(QuicConnectionTest, MtuDiscoveryEnabled) {
  MtuDiscoveryTestInit();
  const QuicPacketCount packets_between_probes_base = 5;
  set_packets_between_probes_base(packets_between_probes_base);
  connection_.EnablePathMtuDiscovery(send_algorithm_);
  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
  }
  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
                       nullptr);
  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
  QuicByteCount probe_size;
  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
      .WillOnce(SaveArg<3>(&probe_size));
  connection_.GetMtuDiscoveryAlarm()->Fire();
  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
                                  kMtuDiscoveryTargetPacketSizeHigh));
  const QuicPacketNumber probe_packet_number =
      FirstSendingPacketNumber() + packets_between_probes_base;
  ASSERT_EQ(probe_packet_number, creator_->packet_number());
  QuicAckFrame probe_ack = InitAckFrame(probe_packet_number);
  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
      .Times(AnyNumber());
  ProcessAckPacket(&probe_ack);
  EXPECT_EQ(probe_size, connection_.max_packet_length());
  EXPECT_EQ(0u, connection_.GetBytesInFlight());
  EXPECT_EQ(1u, connection_.mtu_probe_count());
  QuicStreamOffset stream_offset = packets_between_probes_base;
  QuicByteCount last_probe_size = 0;
  for (size_t num_probes = 1; num_probes < kMtuDiscoveryAttempts;
       ++num_probes) {
    for (QuicPacketCount i = 0;
         i < (packets_between_probes_base << num_probes) - 1; ++i) {
      SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
      ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
    }
    SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
    ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
    QuicByteCount new_probe_size;
    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
        .WillOnce(SaveArg<3>(&new_probe_size));
    connection_.GetMtuDiscoveryAlarm()->Fire();
    EXPECT_THAT(new_probe_size,
                InRange(probe_size, kMtuDiscoveryTargetPacketSizeHigh));
    EXPECT_EQ(num_probes + 1, connection_.mtu_probe_count());
    QuicAckFrame probe_ack = InitAckFrame(creator_->packet_number());
    ProcessAckPacket(&probe_ack);
    EXPECT_EQ(new_probe_size, connection_.max_packet_length());
    EXPECT_EQ(0u, connection_.GetBytesInFlight());
    last_probe_size = probe_size;
    probe_size = new_probe_size;
  }
  EXPECT_EQ(probe_size, kMtuDiscoveryTargetPacketSizeHigh);
  if (GetQuicReloadableFlag(quic_ignore_one_write_error_after_mtu_probe)) {
    writer_->SetShouldWriteFail();
    SendStreamDataToPeer(3, "(", stream_offset++, NO_FIN, nullptr);
    EXPECT_EQ(last_probe_size, connection_.max_packet_length());
    EXPECT_TRUE(connection_.connected());
    EXPECT_CALL(visitor_, OnConnectionClosed(_, _))
        .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
    SendStreamDataToPeer(3, ")", stream_offset++, NO_FIN, nullptr);
    EXPECT_EQ(last_probe_size, connection_.max_packet_length());
    EXPECT_FALSE(connection_.connected());
    EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
                IsError(QUIC_PACKET_WRITE_ERROR));
  }
}
TEST_P ( QuicConnectionTest , MtuDiscoveryEnabled ) { MtuDiscoveryTestInit ( ) ; const QuicPacketCount packets_between_probes_base = 5 ; set_packets_between_probes_base ( packets_between_probes_base ) ; connection_ . EnablePathMtuDiscovery ( send_algorithm_ ) ; for ( QuicPacketCount i = 0 ; i < packets_between_probes_base - 1 ; i ++ ) { SendStreamDataToPeer ( 3 , " " , i , NO_FIN , nullptr ) ; ASSERT_FALSE ( connection_ . GetMtuDiscoveryAlarm ( ) -> IsSet ( ) ) ; } SendStreamDataToPeer ( 3 , " " , packets_between_probes_base - 1 , NO_FIN , nullptr ) ; ASSERT_TRUE ( connection_ . GetMtuDiscoveryAlarm ( ) -> IsSet ( ) ) ; QuicByteCount probe_size ; EXPECT_CALL ( * send_algorithm_ , OnPacketSent ( _ , _ , _ , _ , _ ) ) . WillOnce ( SaveArg < 3 > ( & probe_size ) ) ; connection_ . GetMtuDiscoveryAlarm ( ) -> Fire ( ) ; EXPECT_THAT ( probe_size , InRange ( connection_ . max_packet_length ( ) , kMtuDiscoveryTargetPacketSizeHigh ) ) ; const QuicPacketNumber probe_packet_number = FirstSendingPacketNumber ( ) + packets_between_probes_base ; ASSERT_EQ ( probe_packet_number , creator_ -> packet_number ( ) ) ; QuicAckFrame probe_ack = InitAckFrame ( probe_packet_number ) ; EXPECT_CALL ( * send_algorithm_ , OnCongestionEvent ( true , _ , _ , _ , _ ) ) . Times ( AnyNumber ( ) ) ; ProcessAckPacket ( & probe_ack ) ; EXPECT_EQ ( probe_size , connection_ . max_packet_length ( ) ) ; EXPECT_EQ ( 0u , connection_ . GetBytesInFlight ( ) ) ; EXPECT_EQ ( 1u , connection_ . mtu_probe_count ( ) ) ; QuicStreamOffset stream_offset = packets_between_probes_base ; QuicByteCount last_probe_size = 0 ; for ( size_t num_probes = 1 ; num_probes < kMtuDiscoveryAttempts ; ++ num_probes ) { for ( QuicPacketCount i = 0 ; i < ( packets_between_probes_base << num_probes ) - 1 ; ++ i ) { SendStreamDataToPeer ( 3 , " " , stream_offset ++ , NO_FIN , nullptr ) ; ASSERT_FALSE ( connection_ . GetMtuDiscoveryAlarm ( ) -> IsSet ( ) ) ; } SendStreamDataToPeer ( 3 , " " , stream_offset ++ , NO_FIN , nullptr ) ; ASSERT_TRUE ( connection_ . GetMtuDiscoveryAlarm ( ) -> IsSet ( ) ) ; QuicByteCount new_probe_size ; EXPECT_CALL ( * send_algorithm_ , OnPacketSent ( _ , _ , _ , _ , _ ) ) . WillOnce ( SaveArg < 3 > ( & new_probe_size ) ) ; connection_ . GetMtuDiscoveryAlarm ( ) -> Fire ( ) ; EXPECT_THAT ( new_probe_size , InRange ( probe_size , kMtuDiscoveryTargetPacketSizeHigh ) ) ; EXPECT_EQ ( num_probes + 1 , connection_ . mtu_probe_count ( ) ) ; QuicAckFrame probe_ack = InitAckFrame ( creator_ -> packet_number ( ) ) ; ProcessAckPacket ( & probe_ack ) ; EXPECT_EQ ( new_probe_size , connection_ . max_packet_length ( ) ) ; EXPECT_EQ ( 0u , connection_ . GetBytesInFlight ( ) ) ; last_probe_size = probe_size ; probe_size = new_probe_size ; } EXPECT_EQ ( probe_size , kMtuDiscoveryTargetPacketSizeHigh ) ; if ( GetQuicReloadableFlag ( quic_ignore_one_write_error_after_mtu_probe ) ) { writer_ -> SetShouldWriteFail ( ) ; SendStreamDataToPeer ( 3 , " " , stream_offset ++ , NO_FIN , nullptr ) ; EXPECT_EQ ( last_probe_size , connection_ . max_packet_length ( ) ) ; EXPECT_TRUE ( connection_ . connected ( ) ) ; EXPECT_CALL ( visitor_ , OnConnectionClosed ( _ , _ ) ) . WillOnce ( Invoke ( this , & QuicConnectionTest :: SaveConnectionCloseFrame ) ) ; SendStreamDataToPeer ( 3 , " " , stream_offset ++ , NO_FIN , nullptr ) ; EXPECT_EQ ( last_probe_size , connection_ . max_packet_length ( ) ) ; EXPECT_FALSE ( connection_ . connected ( ) ) ; EXPECT_THAT ( saved_connection_close_frame_ . quic_error_code , IsError ( QUIC_PACKET_WRITE_ERROR ) ) ; } }
Tests whether MTU discovery works when all probes are acknowledged on the
first try.
Tests whether MTU discovery works when all probes are acknowledged on the first try .
// Send enough packets so that the next one triggers path MTU discovery. // Trigger the probe. // Acknowledge all packets sent so far. // Send just enough packets without triggering the next probe. // Trigger the next probe. // Acknowledge all packets sent so far. // The last probe size should be equal to the target. // Ignore PACKET_WRITE_ERROR once. // Close connection on another PACKET_WRITE_ERROR.