зеркало из https://github.com/microsoft/msquic.git
Support FIFO and Round Robin Priority Schemes (#47)
This commit is contained in:
Родитель
e2892cfad6
Коммит
60716dea32
|
@ -13,14 +13,12 @@ jobs:
|
|||
submodules: recursive
|
||||
|
||||
- task: VSBuild@1
|
||||
continueOnError: true
|
||||
inputs:
|
||||
solution: msquic.kernel.sln
|
||||
platform: ${{ parameters.arch }}
|
||||
configuration: debug
|
||||
|
||||
- task: VSBuild@1
|
||||
continueOnError: true
|
||||
inputs:
|
||||
solution: msquic.kernel.sln
|
||||
platform: ${{ parameters.arch }}
|
||||
|
|
|
@ -4868,6 +4868,34 @@ QuicConnParamSet(
|
|||
Status = QUIC_STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case QUIC_PARAM_CONN_STREAM_SCHEDULING_SCHEME: {
|
||||
|
||||
if (BufferLength != sizeof(QUIC_STREAM_SCHEDULING_SCHEME)) {
|
||||
Status = QUIC_STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
QUIC_STREAM_SCHEDULING_SCHEME Scheme =
|
||||
*(QUIC_STREAM_SCHEDULING_SCHEME*)Buffer;
|
||||
|
||||
if (Scheme >= QUIC_STREAM_SCHEDULING_SCHEME_COUNT) {
|
||||
Status = QUIC_STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
Connection->State.UseRoundRobinStreamScheduling =
|
||||
Scheme == QUIC_STREAM_SCHEDULING_SCHEME_ROUND_ROBIN;
|
||||
|
||||
QuicTraceLogConnInfo(
|
||||
UpdateStreamSchedulingScheme,
|
||||
Connection,
|
||||
"Updated Stream Scheduling Scheme = %u",
|
||||
Scheme);
|
||||
|
||||
Status = QUIC_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case QUIC_PARAM_CONN_FORCE_KEY_UPDATE:
|
||||
|
||||
if (!Connection->State.Connected ||
|
||||
|
@ -5395,6 +5423,27 @@ QuicConnParamGet(
|
|||
Status = QUIC_STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case QUIC_PARAM_CONN_STREAM_SCHEDULING_SCHEME:
|
||||
|
||||
if (*BufferLength < sizeof(QUIC_STREAM_SCHEDULING_SCHEME)) {
|
||||
*BufferLength = sizeof(QUIC_STREAM_SCHEDULING_SCHEME);
|
||||
Status = QUIC_STATUS_BUFFER_TOO_SMALL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Buffer == NULL) {
|
||||
Status = QUIC_STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
*BufferLength = sizeof(QUIC_STREAM_SCHEDULING_SCHEME);
|
||||
*(QUIC_STREAM_SCHEDULING_SCHEME*)Buffer =
|
||||
Connection->State.UseRoundRobinStreamScheduling ?
|
||||
QUIC_STREAM_SCHEDULING_SCHEME_ROUND_ROBIN : QUIC_STREAM_SCHEDULING_SCHEME_FIFO;
|
||||
|
||||
Status = QUIC_STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = QUIC_STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
|
|
|
@ -131,10 +131,16 @@ typedef union QUIC_CONNECTION_STATE {
|
|||
BOOLEAN ShareBinding : 1;
|
||||
|
||||
//
|
||||
// Indicate the TestTransportParameter variable has been set by the app.
|
||||
// Indicates the TestTransportParameter variable has been set by the app.
|
||||
//
|
||||
BOOLEAN TestTransportParameterSet : 1;
|
||||
|
||||
//
|
||||
// Indicates the connection is using the round robin stream scheduling
|
||||
// scheme.
|
||||
//
|
||||
BOOLEAN UseRoundRobinStreamScheduling : 1;
|
||||
|
||||
#ifdef QuicVerifierEnabledByAddr
|
||||
//
|
||||
// The calling app is being verified (app or driver verifier).
|
||||
|
|
|
@ -159,7 +159,7 @@ typedef struct QUIC_PATH QUIC_PATH;
|
|||
// The number of packets we write for a single stream before going to the next
|
||||
// one in the round robin.
|
||||
//
|
||||
#define QUIC_STREAM_SEND_BATCH_COUNT 4
|
||||
#define QUIC_STREAM_SEND_BATCH_COUNT 8
|
||||
|
||||
//
|
||||
// The maximum number of received packets to batch process at a time.
|
||||
|
|
|
@ -803,7 +803,8 @@ QuicSendGetNextStream(
|
|||
_Out_ uint32_t* PacketCount
|
||||
)
|
||||
{
|
||||
QUIC_DBG_ASSERT(!QuicConnIsClosed(QuicSendGetConnection(Send)) || QuicListIsEmpty(&Send->SendStreams));
|
||||
QUIC_CONNECTION* Connection = QuicSendGetConnection(Send);
|
||||
QUIC_DBG_ASSERT(!QuicConnIsClosed(Connection) || QuicListIsEmpty(&Send->SendStreams));
|
||||
|
||||
QUIC_LIST_ENTRY* Entry = Send->SendStreams.Flink;
|
||||
while (Entry != &Send->SendStreams) {
|
||||
|
@ -821,13 +822,19 @@ QuicSendGetNextStream(
|
|||
//
|
||||
if (QuicSendCanSendStreamNow(Stream)) {
|
||||
|
||||
//
|
||||
// Move the stream to the end of the queue.
|
||||
//
|
||||
QuicListEntryRemove(&Stream->SendLink);
|
||||
QuicListInsertTail(&Send->SendStreams, &Stream->SendLink);
|
||||
if (Connection->State.UseRoundRobinStreamScheduling) {
|
||||
//
|
||||
// Move the stream to the end of the queue.
|
||||
//
|
||||
QuicListEntryRemove(&Stream->SendLink);
|
||||
QuicListInsertTail(&Send->SendStreams, &Stream->SendLink);
|
||||
|
||||
*PacketCount = QUIC_STREAM_SEND_BATCH_COUNT;
|
||||
|
||||
} else { // FIFO prioritization scheme
|
||||
*PacketCount = UINT32_MAX;
|
||||
}
|
||||
|
||||
*PacketCount = QUIC_STREAM_SEND_BATCH_COUNT;
|
||||
return Stream;
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,12 @@ typedef enum QUIC_CONNECTION_SHUTDOWN_FLAGS {
|
|||
|
||||
DEFINE_ENUM_FLAG_OPERATORS(QUIC_CONNECTION_SHUTDOWN_FLAGS);
|
||||
|
||||
typedef enum QUIC_STREAM_SCHEDULING_SCHEME {
|
||||
QUIC_STREAM_SCHEDULING_SCHEME_FIFO = 0x0000, // Sends stream data first come, first served. (Default)
|
||||
QUIC_STREAM_SCHEDULING_SCHEME_ROUND_ROBIN = 0x0001, // Sends stream data evenly multiplexed.
|
||||
QUIC_STREAM_SCHEDULING_SCHEME_COUNT // The number of stream scheduling schemes.
|
||||
} QUIC_STREAM_SCHEDULING_SCHEME;
|
||||
|
||||
typedef enum QUIC_STREAM_OPEN_FLAGS {
|
||||
QUIC_STREAM_OPEN_FLAG_NONE = 0x0000,
|
||||
QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL = 0x0001, // Indicates the stream is unidirectional.
|
||||
|
@ -358,6 +364,7 @@ typedef enum QUIC_PARAM_LEVEL {
|
|||
#define QUIC_PARAM_CONN_SHARE_UDP_BINDING 17 // uint8_t (BOOLEAN)
|
||||
#define QUIC_PARAM_CONN_IDEAL_PROCESSOR 18 // uint8_t
|
||||
#define QUIC_PARAM_CONN_MAX_STREAM_IDS 19 // uint64_t[4]
|
||||
#define QUIC_PARAM_CONN_STREAM_SCHEDULING_SCHEME 20 // QUIC_STREAM_SCHEDULING_SCHEME
|
||||
|
||||
#ifdef WIN32 // Windows certificate validation ignore flags.
|
||||
#define QUIC_CERTIFICATE_FLAG_IGNORE_REVOCATION 0x00000080
|
||||
|
|
|
@ -122,7 +122,8 @@ QuicTestConnectAndPing(
|
|||
_In_ bool ServerRejectZeroRtt,
|
||||
_In_ bool UseSendBuffer,
|
||||
_In_ bool UnidirectionalStreams,
|
||||
_In_ bool ServerInitiatedStreams
|
||||
_In_ bool ServerInitiatedStreams,
|
||||
_In_ bool FifoScheduling
|
||||
);
|
||||
|
||||
//
|
||||
|
@ -379,6 +380,7 @@ typedef struct {
|
|||
uint8_t UseSendBuffer;
|
||||
uint8_t UnidirectionalStreams;
|
||||
uint8_t ServerInitiatedStreams;
|
||||
uint8_t FifoScheduling;
|
||||
} QUIC_RUN_CONNECT_AND_PING_PARAMS;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
|
|
@ -529,11 +529,12 @@ TEST_P(WithSendArgs1, Send) {
|
|||
0, // StreamBurstDelayMs
|
||||
0, // ServerStatelessRetry
|
||||
0, // ClientRebind
|
||||
0, // ClientZeroRtt,
|
||||
0, // ClientZeroRtt
|
||||
0, // ServerRejectZeroRtt
|
||||
(uint8_t)GetParam().UseSendBuffer,
|
||||
(uint8_t)GetParam().UnidirectionalStreams,
|
||||
(uint8_t)GetParam().ServerInitiatedStreams
|
||||
(uint8_t)GetParam().ServerInitiatedStreams,
|
||||
0 // FifoScheduling
|
||||
};
|
||||
ASSERT_TRUE(DriverClient.Run(IOCTL_QUIC_RUN_CONNECT_AND_PING, Params));
|
||||
} else {
|
||||
|
@ -550,7 +551,8 @@ TEST_P(WithSendArgs1, Send) {
|
|||
false, // ServerRejectZeroRtt
|
||||
GetParam().UseSendBuffer,
|
||||
GetParam().UnidirectionalStreams,
|
||||
GetParam().ServerInitiatedStreams);
|
||||
GetParam().ServerInitiatedStreams,
|
||||
false); // FifoScheduling
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -570,7 +572,8 @@ TEST_P(WithSendArgs2, SendLarge) {
|
|||
0, // ServerRejectZeroRtt
|
||||
(uint8_t)GetParam().UseSendBuffer,
|
||||
0, // UnidirectionalStreams
|
||||
0 // ServerInitiatedStreams
|
||||
0, // ServerInitiatedStreams
|
||||
1 // FifoScheduling
|
||||
};
|
||||
ASSERT_TRUE(DriverClient.Run(IOCTL_QUIC_RUN_CONNECT_AND_PING, Params));
|
||||
} else {
|
||||
|
@ -587,7 +590,8 @@ TEST_P(WithSendArgs2, SendLarge) {
|
|||
false, // ServerRejectZeroRtt
|
||||
GetParam().UseSendBuffer,
|
||||
false, // UnidirectionalStreams
|
||||
false); // ServerInitiatedStreams
|
||||
false, // ServerInitiatedStreams
|
||||
true); // FifoScheduling
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,7 +611,8 @@ TEST_P(WithSendArgs3, SendIntermittently) {
|
|||
0, // ServerRejectZeroRtt
|
||||
(uint8_t)GetParam().UseSendBuffer,
|
||||
0, // UnidirectionalStreams
|
||||
0 // ServerInitiatedStreams
|
||||
0, // ServerInitiatedStreams
|
||||
0 // FifoScheduling
|
||||
};
|
||||
ASSERT_TRUE(DriverClient.Run(IOCTL_QUIC_RUN_CONNECT_AND_PING, Params));
|
||||
} else {
|
||||
|
@ -624,7 +629,8 @@ TEST_P(WithSendArgs3, SendIntermittently) {
|
|||
false, // ServerRejectZeroRtt
|
||||
GetParam().UseSendBuffer,
|
||||
false, // UnidirectionalStreams
|
||||
false); // ServerInitiatedStreams
|
||||
false, // ServerInitiatedStreams
|
||||
false); // FifoScheduling
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -646,7 +652,8 @@ TEST_P(WithSend0RttArgs1, Send0Rtt) {
|
|||
0, // ServerRejectZeroRtt
|
||||
(uint8_t)GetParam().UseSendBuffer,
|
||||
(uint8_t)GetParam().UnidirectionalStreams,
|
||||
0 // ServerInitiatedStreams
|
||||
0, // ServerInitiatedStreams
|
||||
0 // FifoScheduling
|
||||
};
|
||||
ASSERT_TRUE(DriverClient.Run(IOCTL_QUIC_RUN_CONNECT_AND_PING, Params));
|
||||
} else {
|
||||
|
@ -663,7 +670,8 @@ TEST_P(WithSend0RttArgs1, Send0Rtt) {
|
|||
false, // ServerRejectZeroRtt
|
||||
GetParam().UseSendBuffer,
|
||||
GetParam().UnidirectionalStreams,
|
||||
false); // ServerInitiatedStreams
|
||||
false, // ServerInitiatedStreams
|
||||
false); // FifoScheduling
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -683,7 +691,8 @@ TEST_P(WithSend0RttArgs2, Reject0Rtt) {
|
|||
1, // ServerRejectZeroRtt
|
||||
0, // UseSendBuffer
|
||||
0, // UnidirectionalStreams
|
||||
0 // ServerInitiatedStreams
|
||||
0, // ServerInitiatedStreams
|
||||
0 // FifoScheduling
|
||||
};
|
||||
ASSERT_TRUE(DriverClient.Run(IOCTL_QUIC_RUN_CONNECT_AND_PING, Params));
|
||||
} else {
|
||||
|
@ -700,7 +709,8 @@ TEST_P(WithSend0RttArgs2, Reject0Rtt) {
|
|||
true, // ServerRejectZeroRtt
|
||||
false, // UseSendBuffer
|
||||
false, // UnidirectionalStreams
|
||||
false); // ServerInitiatedStreams
|
||||
false, // ServerInitiatedStreams
|
||||
false); // FifoScheduling
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -703,7 +703,8 @@ QuicTestCtlEvtIoDeviceControl(
|
|||
Params->Params2.ServerRejectZeroRtt != 0,
|
||||
Params->Params2.UseSendBuffer != 0,
|
||||
Params->Params2.UnidirectionalStreams != 0,
|
||||
Params->Params2.ServerInitiatedStreams != 0
|
||||
Params->Params2.ServerInitiatedStreams != 0,
|
||||
Params->Params2.FifoScheduling != 0
|
||||
));
|
||||
break;
|
||||
|
||||
|
|
|
@ -607,6 +607,7 @@ struct PingStats
|
|||
const uint64_t PayloadLength;
|
||||
const uint32_t ConnectionCount;
|
||||
const uint32_t StreamCount;
|
||||
const bool FifoScheduling;
|
||||
const bool UnidirectionalStreams;
|
||||
const bool ServerInitiatedStreams;
|
||||
const bool ZeroRtt;
|
||||
|
@ -622,6 +623,7 @@ struct PingStats
|
|||
uint64_t _PayloadLength,
|
||||
uint32_t _ConnectionCount,
|
||||
uint32_t _StreamCount,
|
||||
bool _FifoScheduling,
|
||||
bool _UnidirectionalStreams,
|
||||
bool _ServerInitiatedStreams,
|
||||
bool _ZeroRtt,
|
||||
|
@ -632,6 +634,7 @@ struct PingStats
|
|||
PayloadLength(_PayloadLength),
|
||||
ConnectionCount(_ConnectionCount),
|
||||
StreamCount(_StreamCount),
|
||||
FifoScheduling(_FifoScheduling),
|
||||
UnidirectionalStreams(_UnidirectionalStreams),
|
||||
ServerInitiatedStreams(_ServerInitiatedStreams),
|
||||
ZeroRtt(_ZeroRtt),
|
||||
|
@ -701,6 +704,7 @@ PingStreamShutdown(
|
|||
|
||||
#if !QUIC_SEND_FAKE_LOSS
|
||||
if (!ConnState->GetPingStats()->ServerInitiatedStreams &&
|
||||
!ConnState->GetPingStats()->FifoScheduling &&
|
||||
ConnState->GetPingStats()->ZeroRtt) {
|
||||
if (Stream->GetBytesReceived() != 0 && // TODO - Support 0-RTT indication for Stream Open callback.
|
||||
!Stream->GetUsedZeroRtt()) {
|
||||
|
@ -811,6 +815,11 @@ ListenerAcceptPingConnection(
|
|||
}
|
||||
}
|
||||
|
||||
Connection->SetPriorityScheme(
|
||||
Stats->FifoScheduling ?
|
||||
QUIC_STREAM_SCHEDULING_SCHEME_FIFO :
|
||||
QUIC_STREAM_SCHEDULING_SCHEME_ROUND_ROBIN);
|
||||
|
||||
if (Stats->ServerInitiatedStreams) {
|
||||
SendPingBurst(
|
||||
Connection,
|
||||
|
@ -849,6 +858,11 @@ NewPingConnection(
|
|||
Connection->SetShutdownCompleteCallback(PingConnectionShutdown);
|
||||
Connection->SetExpectedResumed(ClientStats->ZeroRtt);
|
||||
|
||||
Connection->SetPriorityScheme(
|
||||
ClientStats->FifoScheduling ?
|
||||
QUIC_STREAM_SCHEDULING_SCHEME_FIFO :
|
||||
QUIC_STREAM_SCHEDULING_SCHEME_ROUND_ROBIN);
|
||||
|
||||
if (ClientStats->ServerInitiatedStreams) {
|
||||
Connection->SetPeerUnidiStreamCount((uint16_t)ClientStats->StreamCount);
|
||||
Connection->SetPeerBidiStreamCount((uint16_t)ClientStats->StreamCount);
|
||||
|
@ -875,14 +889,15 @@ QuicTestConnectAndPing(
|
|||
_In_ bool ServerRejectZeroRtt,
|
||||
_In_ bool UseSendBuffer,
|
||||
_In_ bool UnidirectionalStreams,
|
||||
_In_ bool ServerInitiatedStreams
|
||||
_In_ bool ServerInitiatedStreams,
|
||||
_In_ bool FifoScheduling
|
||||
)
|
||||
{
|
||||
const uint32_t TimeoutMs = EstimateTimeoutMs(Length) * StreamBurstCount;
|
||||
const uint16_t TotalStreamCount = (uint16_t)(StreamCount * StreamBurstCount);
|
||||
|
||||
PingStats ServerStats(Length, ConnectionCount, TotalStreamCount, UnidirectionalStreams, ServerInitiatedStreams, ClientZeroRtt && !ServerRejectZeroRtt, false, QUIC_STATUS_SUCCESS);
|
||||
PingStats ClientStats(Length, ConnectionCount, TotalStreamCount, UnidirectionalStreams, ServerInitiatedStreams, ClientZeroRtt && !ServerRejectZeroRtt);
|
||||
PingStats ServerStats(Length, ConnectionCount, TotalStreamCount, FifoScheduling, UnidirectionalStreams, ServerInitiatedStreams, ClientZeroRtt && !ServerRejectZeroRtt, false, QUIC_STATUS_SUCCESS);
|
||||
PingStats ClientStats(Length, ConnectionCount, TotalStreamCount, FifoScheduling, UnidirectionalStreams, ServerInitiatedStreams, ClientZeroRtt && !ServerRejectZeroRtt);
|
||||
|
||||
MsQuicSession Session;
|
||||
TEST_TRUE(Session.IsValid());
|
||||
|
@ -1098,8 +1113,8 @@ QuicTestServerDisconnect(
|
|||
void
|
||||
)
|
||||
{
|
||||
PingStats ServerStats(UINT64_MAX - 1, 1, 1, TRUE, TRUE, FALSE, TRUE, QUIC_STATUS_CONNECTION_TIMEOUT);
|
||||
PingStats ClientStats(UINT64_MAX - 1, 1, 1, TRUE, TRUE, FALSE, TRUE);
|
||||
PingStats ServerStats(UINT64_MAX - 1, 1, 1, TRUE, TRUE, TRUE, FALSE, TRUE, QUIC_STATUS_CONNECTION_TIMEOUT);
|
||||
PingStats ClientStats(UINT64_MAX - 1, 1, 1, TRUE, TRUE, TRUE, FALSE, TRUE);
|
||||
|
||||
{
|
||||
MsQuicSession Session;
|
||||
|
@ -1206,7 +1221,7 @@ QuicTestClientDisconnect(
|
|||
// back to the client as it continues to receive the client's UDP packets.
|
||||
//
|
||||
|
||||
PingStats ClientStats(UINT64_MAX - 1, 1, 1, TRUE, FALSE, FALSE, TRUE,
|
||||
PingStats ClientStats(UINT64_MAX - 1, 1, 1, TRUE, TRUE, FALSE, FALSE, TRUE,
|
||||
StopListenerFirst ? QUIC_STATUS_CONNECTION_TIMEOUT : QUIC_STATUS_ABORTED);
|
||||
|
||||
{
|
||||
|
|
|
@ -643,6 +643,39 @@ TestConnection::SetShareUdpBinding(
|
|||
&bValue);
|
||||
}
|
||||
|
||||
QUIC_STREAM_SCHEDULING_SCHEME
|
||||
TestConnection::GetPriorityScheme()
|
||||
{
|
||||
QUIC_STREAM_SCHEDULING_SCHEME value;
|
||||
uint32_t valueSize = sizeof(value);
|
||||
QUIC_STATUS Status =
|
||||
MsQuic->GetParam(
|
||||
QuicConnection,
|
||||
QUIC_PARAM_LEVEL_CONNECTION,
|
||||
QUIC_PARAM_CONN_STREAM_SCHEDULING_SCHEME,
|
||||
&valueSize,
|
||||
&value);
|
||||
if (QUIC_FAILED(Status)) {
|
||||
value = QUIC_STREAM_SCHEDULING_SCHEME_FIFO;
|
||||
TEST_FAILURE("MsQuic->GetParam(CONN_PRIORITY_SCHEME) failed, 0x%x.", Status);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
QUIC_STATUS
|
||||
TestConnection::SetPriorityScheme(
|
||||
QUIC_STREAM_SCHEDULING_SCHEME value
|
||||
)
|
||||
{
|
||||
return
|
||||
MsQuic->SetParam(
|
||||
QuicConnection,
|
||||
QUIC_PARAM_LEVEL_CONNECTION,
|
||||
QUIC_PARAM_CONN_STREAM_SCHEDULING_SCHEME,
|
||||
sizeof(value),
|
||||
&value);
|
||||
}
|
||||
|
||||
QUIC_STATUS
|
||||
TestConnection::SetSecurityConfig(
|
||||
QUIC_SEC_CONFIG* value
|
||||
|
|
|
@ -210,6 +210,9 @@ public:
|
|||
bool GetShareUdpBinding();
|
||||
QUIC_STATUS SetShareUdpBinding(bool value);
|
||||
|
||||
QUIC_STREAM_SCHEDULING_SCHEME GetPriorityScheme();
|
||||
QUIC_STATUS SetPriorityScheme(QUIC_STREAM_SCHEDULING_SCHEME value);
|
||||
|
||||
QUIC_STATUS SetSecurityConfig(QUIC_SEC_CONFIG* value);
|
||||
|
||||
bool HasNewZeroRttTicket();
|
||||
|
|
Загрузка…
Ссылка в новой задаче