diff --git a/quic/api/QuicTransportBase.cpp b/quic/api/QuicTransportBase.cpp index 10bab4ddc..d23662866 100644 --- a/quic/api/QuicTransportBase.cpp +++ b/quic/api/QuicTransportBase.cpp @@ -3805,10 +3805,17 @@ void QuicTransportBase::onStreamPrioritiesChange() { conn_->congestionController->setBandwidthUtilizationFactor(targetUtilization); } +bool QuicTransportBase::checkCustomRetransmissionProfilesEnabled() const { + return quic::checkCustomRetransmissionProfilesEnabled(*conn_); +} + folly::Expected QuicTransportBase::setStreamGroupRetransmissionPolicy( StreamGroupId /* groupId */, QuicStreamGroupRetransmissionPolicy /* policy */) noexcept { + if (!checkCustomRetransmissionProfilesEnabled()) { + return folly::makeUnexpected(LocalErrorCode::INVALID_OPERATION); + } return folly::unit; } diff --git a/quic/api/QuicTransportBase.h b/quic/api/QuicTransportBase.h index 9ce773dc3..b13a9e849 100644 --- a/quic/api/QuicTransportBase.h +++ b/quic/api/QuicTransportBase.h @@ -654,6 +654,9 @@ class QuicTransportBase : public QuicSocket, QuicStreamPrioritiesObserver { void appendCmsgs(const folly::SocketOptionMap& options); + /** + * Sets stream group retransmission policy. + */ folly::Expected setStreamGroupRetransmissionPolicy( StreamGroupId groupId, @@ -959,6 +962,13 @@ class QuicTransportBase : public QuicSocket, QuicStreamPrioritiesObserver { * Helper to log new stream event to observer. */ void logStreamOpenEvent(StreamId streamId); + + /** + * Helper to check if using custom retransmission profiles is feasible. + * Custom retransmission profiles are only applicable when stream groups are + * enabled, i.e. advertisedMaxStreamGroups in transport settings is > 0. + */ + [[nodiscard]] bool checkCustomRetransmissionProfilesEnabled() const; }; std::ostream& operator<<(std::ostream& os, const QuicTransportBase& qt); diff --git a/quic/api/test/QuicTransportBaseTest.cpp b/quic/api/test/QuicTransportBaseTest.cpp index c8a726c53..98a0c2922 100644 --- a/quic/api/test/QuicTransportBaseTest.cpp +++ b/quic/api/test/QuicTransportBaseTest.cpp @@ -4430,5 +4430,33 @@ TEST_P(QuicTransportImplTestWithGroups, onNewStreamsAndGroupsCallbacks) { transport.reset(); } +TEST_P( + QuicTransportImplTestWithGroups, + TestSetStreamGroupRetransmissionPolicyAllowed) { + auto transportSettings = transport->getTransportSettings(); + transportSettings.advertisedMaxStreamGroups = 16; + transport->setTransportSettings(transportSettings); + transport->getConnectionState().streamManager->refreshTransportSettings( + transportSettings); + + const StreamGroupId groupId = 0x00; + const QuicStreamGroupRetransmissionPolicy policy; + + // Test policy set allowed + auto res = transport->setStreamGroupRetransmissionPolicy(groupId, policy); + EXPECT_TRUE(res.hasValue()); + + // Test policy set not allowed. + transportSettings.advertisedMaxStreamGroups = 0; + transport->setTransportSettings(transportSettings); + transport->getConnectionState().streamManager->refreshTransportSettings( + transportSettings); + res = transport->setStreamGroupRetransmissionPolicy(groupId, policy); + EXPECT_TRUE(res.hasError()); + EXPECT_EQ(res.error(), LocalErrorCode::INVALID_OPERATION); + + transport.reset(); +} + } // namespace test } // namespace quic diff --git a/quic/state/QuicStateFunctions.cpp b/quic/state/QuicStateFunctions.cpp index ac0fe5a04..9ca6fc49f 100644 --- a/quic/state/QuicStateFunctions.cpp +++ b/quic/state/QuicStateFunctions.cpp @@ -432,4 +432,9 @@ uint64_t updateLargestReceivedPacketNum( } } +bool checkCustomRetransmissionProfilesEnabled( + const QuicConnectionStateBase& conn) { + return conn.transportSettings.advertisedMaxStreamGroups > 0; +} + } // namespace quic diff --git a/quic/state/QuicStateFunctions.h b/quic/state/QuicStateFunctions.h index fda1dca73..0feb41a52 100644 --- a/quic/state/QuicStateFunctions.h +++ b/quic/state/QuicStateFunctions.h @@ -110,4 +110,7 @@ std::pair, PacketNumberSpace> earliestTimeAndSpace( uint64_t maximumConnectionIdsToIssue(const QuicConnectionStateBase& conn); +bool checkCustomRetransmissionProfilesEnabled( + const QuicConnectionStateBase& conn); + } // namespace quic