mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-12-03 03:40:56 +03:00
Always update max packet size after 0-rtt.
Summary: This is a temporary hack until we properly implement 0-rtt transport parameter updating. Now after 0-rtt we will use the packet size from the peer as the max packet size, if the can ignore setting is set. Reviewed By: xttjsn Differential Revision: D23690019 fbshipit-source-id: b4dbf5702e81e52ccd437e0fa68f4d156c7123be
This commit is contained in:
committed by
Facebook GitHub Bot
parent
2c377ea5d3
commit
43a0b7e02d
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <folly/portability/Sockets.h>
|
#include <folly/portability/Sockets.h>
|
||||||
|
|
||||||
|
#include <quic/QuicConstants.h>
|
||||||
#include <quic/api/LoopDetectorCallback.h>
|
#include <quic/api/LoopDetectorCallback.h>
|
||||||
#include <quic/api/QuicTransportFunctions.h>
|
#include <quic/api/QuicTransportFunctions.h>
|
||||||
#include <quic/client/handshake/ClientHandshakeFactory.h>
|
#include <quic/client/handshake/ClientHandshakeFactory.h>
|
||||||
@@ -531,72 +532,89 @@ void QuicClientTransport::processPacketData(
|
|||||||
// We should get transport parameters if we've derived 1-rtt keys and 0-rtt
|
// We should get transport parameters if we've derived 1-rtt keys and 0-rtt
|
||||||
// was rejected, or we have derived 1-rtt keys and 0-rtt was never
|
// was rejected, or we have derived 1-rtt keys and 0-rtt was never
|
||||||
// attempted.
|
// attempted.
|
||||||
if ((oneRttKeyDerivationTriggered &&
|
if (oneRttKeyDerivationTriggered) {
|
||||||
((zeroRttRejected.has_value() && *zeroRttRejected) ||
|
|
||||||
!zeroRttRejected.has_value()))) {
|
|
||||||
auto originalPeerMaxOffset =
|
|
||||||
conn_->flowControlState.peerAdvertisedMaxOffset;
|
|
||||||
auto originalPeerInitialStreamOffsetBidiLocal =
|
|
||||||
conn_->flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal;
|
|
||||||
auto originalPeerInitialStreamOffsetBidiRemote =
|
|
||||||
conn_->flowControlState
|
|
||||||
.peerAdvertisedInitialMaxStreamOffsetBidiRemote;
|
|
||||||
auto originalPeerInitialStreamOffsetUni =
|
|
||||||
conn_->flowControlState.peerAdvertisedInitialMaxStreamOffsetUni;
|
|
||||||
VLOG(10) << "Client negotiated transport params " << *this;
|
|
||||||
auto serverParams = handshakeLayer->getServerTransportParams();
|
auto serverParams = handshakeLayer->getServerTransportParams();
|
||||||
if (!serverParams) {
|
if (!serverParams) {
|
||||||
throw QuicTransportException(
|
throw QuicTransportException(
|
||||||
"No server transport params",
|
"No server transport params",
|
||||||
TransportErrorCode::TRANSPORT_PARAMETER_ERROR);
|
TransportErrorCode::TRANSPORT_PARAMETER_ERROR);
|
||||||
}
|
}
|
||||||
auto maxStreamsBidi = getIntegerParameter(
|
if ((zeroRttRejected.has_value() && *zeroRttRejected) ||
|
||||||
TransportParameterId::initial_max_streams_bidi,
|
!zeroRttRejected.has_value()) {
|
||||||
serverParams->parameters);
|
auto originalPeerMaxOffset =
|
||||||
auto maxStreamsUni = getIntegerParameter(
|
conn_->flowControlState.peerAdvertisedMaxOffset;
|
||||||
TransportParameterId::initial_max_streams_uni,
|
auto originalPeerInitialStreamOffsetBidiLocal =
|
||||||
serverParams->parameters);
|
conn_->flowControlState
|
||||||
processServerInitialParams(
|
.peerAdvertisedInitialMaxStreamOffsetBidiLocal;
|
||||||
*clientConn_, std::move(*serverParams), packetNum);
|
auto originalPeerInitialStreamOffsetBidiRemote =
|
||||||
|
conn_->flowControlState
|
||||||
|
.peerAdvertisedInitialMaxStreamOffsetBidiRemote;
|
||||||
|
auto originalPeerInitialStreamOffsetUni =
|
||||||
|
conn_->flowControlState.peerAdvertisedInitialMaxStreamOffsetUni;
|
||||||
|
VLOG(10) << "Client negotiated transport params " << *this;
|
||||||
|
auto maxStreamsBidi = getIntegerParameter(
|
||||||
|
TransportParameterId::initial_max_streams_bidi,
|
||||||
|
serverParams->parameters);
|
||||||
|
auto maxStreamsUni = getIntegerParameter(
|
||||||
|
TransportParameterId::initial_max_streams_uni,
|
||||||
|
serverParams->parameters);
|
||||||
|
processServerInitialParams(
|
||||||
|
*clientConn_, std::move(*serverParams), packetNum);
|
||||||
|
|
||||||
cacheServerInitialParams(
|
cacheServerInitialParams(
|
||||||
*clientConn_,
|
*clientConn_,
|
||||||
conn_->flowControlState.peerAdvertisedMaxOffset,
|
conn_->flowControlState.peerAdvertisedMaxOffset,
|
||||||
conn_->flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal,
|
conn_->flowControlState
|
||||||
conn_->flowControlState
|
.peerAdvertisedInitialMaxStreamOffsetBidiLocal,
|
||||||
.peerAdvertisedInitialMaxStreamOffsetBidiRemote,
|
conn_->flowControlState
|
||||||
conn_->flowControlState.peerAdvertisedInitialMaxStreamOffsetUni,
|
.peerAdvertisedInitialMaxStreamOffsetBidiRemote,
|
||||||
maxStreamsBidi.value_or(0),
|
conn_->flowControlState.peerAdvertisedInitialMaxStreamOffsetUni,
|
||||||
maxStreamsUni.value_or(0));
|
maxStreamsBidi.value_or(0),
|
||||||
|
maxStreamsUni.value_or(0));
|
||||||
|
|
||||||
auto& statelessResetToken = clientConn_->statelessResetToken;
|
auto& statelessResetToken = clientConn_->statelessResetToken;
|
||||||
if (statelessResetToken) {
|
if (statelessResetToken) {
|
||||||
conn_->readCodec->setStatelessResetToken(*statelessResetToken);
|
conn_->readCodec->setStatelessResetToken(*statelessResetToken);
|
||||||
}
|
}
|
||||||
if (zeroRttRejected.has_value() && *zeroRttRejected) {
|
if (zeroRttRejected.has_value() && *zeroRttRejected) {
|
||||||
// verify that the new flow control parameters are >= the original
|
// verify that the new flow control parameters are >= the original
|
||||||
// transport parameters that were use. This is the easy case. If the
|
// transport parameters that were use. This is the easy case. If the
|
||||||
// flow control decreases then we are just screwed and we need to have
|
// flow control decreases then we are just screwed and we need to have
|
||||||
// the app retry the connection. The other parameters can be updated.
|
// the app retry the connection. The other parameters can be updated.
|
||||||
// TODO: implement undo transport state on retry.
|
// TODO: implement undo transport state on retry.
|
||||||
if (originalPeerMaxOffset >
|
if (originalPeerMaxOffset >
|
||||||
conn_->flowControlState.peerAdvertisedMaxOffset ||
|
conn_->flowControlState.peerAdvertisedMaxOffset ||
|
||||||
originalPeerInitialStreamOffsetBidiLocal >
|
originalPeerInitialStreamOffsetBidiLocal >
|
||||||
conn_->flowControlState
|
conn_->flowControlState
|
||||||
.peerAdvertisedInitialMaxStreamOffsetBidiLocal ||
|
.peerAdvertisedInitialMaxStreamOffsetBidiLocal ||
|
||||||
originalPeerInitialStreamOffsetBidiRemote >
|
originalPeerInitialStreamOffsetBidiRemote >
|
||||||
conn_->flowControlState
|
conn_->flowControlState
|
||||||
.peerAdvertisedInitialMaxStreamOffsetBidiRemote ||
|
.peerAdvertisedInitialMaxStreamOffsetBidiRemote ||
|
||||||
|
|
||||||
originalPeerInitialStreamOffsetUni >
|
originalPeerInitialStreamOffsetUni >
|
||||||
conn_->flowControlState
|
conn_->flowControlState
|
||||||
.peerAdvertisedInitialMaxStreamOffsetUni) {
|
.peerAdvertisedInitialMaxStreamOffsetUni) {
|
||||||
throw QuicTransportException(
|
throw QuicTransportException(
|
||||||
"Rejection of zero rtt parameters unsupported",
|
"Rejection of zero rtt parameters unsupported",
|
||||||
TransportErrorCode::TRANSPORT_PARAMETER_ERROR);
|
TransportErrorCode::TRANSPORT_PARAMETER_ERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO This sucks, but manually update the max packet size until we fix
|
||||||
|
// 0-rtt transport parameters.
|
||||||
|
if (conn_->transportSettings.canIgnorePathMTU &&
|
||||||
|
zeroRttRejected.has_value() && !*zeroRttRejected) {
|
||||||
|
auto updatedPacketSize = getIntegerParameter(
|
||||||
|
TransportParameterId::max_packet_size, serverParams->parameters);
|
||||||
|
updatedPacketSize = std::max<uint64_t>(
|
||||||
|
updatedPacketSize.value_or(kDefaultUDPSendPacketLen),
|
||||||
|
kDefaultUDPSendPacketLen);
|
||||||
|
updatedPacketSize =
|
||||||
|
std::min<uint64_t>(*updatedPacketSize, kDefaultMaxUDPPayload);
|
||||||
|
conn_->udpSendPacketLen = *updatedPacketSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zeroRttRejected.has_value() && *zeroRttRejected) {
|
if (zeroRttRejected.has_value() && *zeroRttRejected) {
|
||||||
// TODO: Make sure the alpn is the same, if not then do a full undo of the
|
// TODO: Make sure the alpn is the same, if not then do a full undo of the
|
||||||
// state.
|
// state.
|
||||||
|
|||||||
@@ -234,9 +234,6 @@ void updateTransportParamsFromCachedEarlyParams(
|
|||||||
QuicClientConnectionState& conn,
|
QuicClientConnectionState& conn,
|
||||||
const CachedServerTransportParameters& transportParams) {
|
const CachedServerTransportParameters& transportParams) {
|
||||||
conn.peerIdleTimeout = std::chrono::milliseconds(transportParams.idleTimeout);
|
conn.peerIdleTimeout = std::chrono::milliseconds(transportParams.idleTimeout);
|
||||||
if (conn.transportSettings.canIgnorePathMTU) {
|
|
||||||
conn.udpSendPacketLen = transportParams.maxRecvPacketSize;
|
|
||||||
}
|
|
||||||
conn.flowControlState.peerAdvertisedMaxOffset =
|
conn.flowControlState.peerAdvertisedMaxOffset =
|
||||||
transportParams.initialMaxData;
|
transportParams.initialMaxData;
|
||||||
conn.flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal =
|
conn.flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal =
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ TEST_F(ClientStateMachineTest, TestUpdateTransportParamsFromCachedEarlyParams) {
|
|||||||
|
|
||||||
updateTransportParamsFromCachedEarlyParams(*client_, kParams);
|
updateTransportParamsFromCachedEarlyParams(*client_, kParams);
|
||||||
EXPECT_EQ(client_->peerIdleTimeout, idleTimeout);
|
EXPECT_EQ(client_->peerIdleTimeout, idleTimeout);
|
||||||
EXPECT_EQ(client_->udpSendPacketLen, maxRecvPacketSize);
|
EXPECT_NE(client_->udpSendPacketLen, maxRecvPacketSize);
|
||||||
EXPECT_EQ(client_->flowControlState.peerAdvertisedMaxOffset, initialMaxData);
|
EXPECT_EQ(client_->flowControlState.peerAdvertisedMaxOffset, initialMaxData);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
client_->flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal,
|
client_->flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiLocal,
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <quic/samples/echo/EchoHandler.h>
|
#include <quic/samples/echo/EchoHandler.h>
|
||||||
#include <quic/samples/echo/EchoServer.h>
|
#include <quic/samples/echo/EchoServer.h>
|
||||||
#include <quic/state/test/MockQuicStats.h>
|
#include <quic/state/test/MockQuicStats.h>
|
||||||
|
#include "quic/QuicConstants.h"
|
||||||
|
|
||||||
using namespace testing;
|
using namespace testing;
|
||||||
using namespace folly;
|
using namespace folly;
|
||||||
@@ -5366,7 +5367,6 @@ TEST_F(QuicZeroRttClientTest, TestReplaySafeCallback) {
|
|||||||
startClient();
|
startClient();
|
||||||
EXPECT_TRUE(performedValidation);
|
EXPECT_TRUE(performedValidation);
|
||||||
|
|
||||||
auto initialUDPSendPacketLen = client->getConn().udpSendPacketLen;
|
|
||||||
socketWrites.clear();
|
socketWrites.clear();
|
||||||
auto streamId = client->createBidirectionalStream().value();
|
auto streamId = client->createBidirectionalStream().value();
|
||||||
client->writeChain(streamId, IOBuf::copyBuffer("hello"), true, false);
|
client->writeChain(streamId, IOBuf::copyBuffer("hello"), true, false);
|
||||||
@@ -5382,12 +5382,13 @@ TEST_F(QuicZeroRttClientTest, TestReplaySafeCallback) {
|
|||||||
// All the data is still there.
|
// All the data is still there.
|
||||||
EXPECT_TRUE(zeroRttPacketsOutstanding());
|
EXPECT_TRUE(zeroRttPacketsOutstanding());
|
||||||
// Transport parameters did not change since zero rtt was accepted.
|
// Transport parameters did not change since zero rtt was accepted.
|
||||||
|
// Except for max packet size.
|
||||||
verifyTransportParameters(
|
verifyTransportParameters(
|
||||||
kDefaultConnectionWindowSize,
|
kDefaultConnectionWindowSize,
|
||||||
kDefaultStreamWindowSize,
|
kDefaultStreamWindowSize,
|
||||||
kDefaultIdleTimeout,
|
kDefaultIdleTimeout,
|
||||||
kDefaultAckDelayExponent,
|
kDefaultAckDelayExponent,
|
||||||
initialUDPSendPacketLen);
|
kDefaultMaxUDPPayload);
|
||||||
|
|
||||||
EXPECT_CALL(*mockQuicPskCache_, putPsk(hostname_, _))
|
EXPECT_CALL(*mockQuicPskCache_, putPsk(hostname_, _))
|
||||||
.WillOnce(Invoke([=](const std::string&, QuicCachedPsk psk) {
|
.WillOnce(Invoke([=](const std::string&, QuicCachedPsk psk) {
|
||||||
|
|||||||
Reference in New Issue
Block a user