This commit is contained in:
Nick Banks 2021-05-11 18:34:18 -07:00 коммит произвёл GitHub
Родитель f9c66984ef
Коммит 6f2efc4a34
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 130 добавлений и 2 удалений

Просмотреть файл

@ -813,6 +813,22 @@ struct MsQuicStream {
return MsQuic->StreamSend(Handle, Buffers, BufferCount, Flags, ClientSendContext);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
QUIC_STATUS
ReceiveComplete(
_In_ uint64_t BufferLength
) noexcept {
return MsQuic->StreamReceiveComplete(Handle, BufferLength);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
QUIC_STATUS
ReceiveSetEnabled(
_In_ bool IsEnabled = true
) noexcept {
return MsQuic->StreamReceiveSetEnabled(Handle, IsEnabled ? TRUE : FALSE);
}
QUIC_STATUS GetInitStatus() const noexcept { return InitStatus; }
bool IsValid() const { return QUIC_SUCCEEDED(InitStatus); }
MsQuicStream(MsQuicStream& other) = delete;

Просмотреть файл

@ -351,6 +351,10 @@ QuicTestAbortReceive(
_In_ QUIC_ABORT_RECEIVE_TYPE Type
);
void
QuicTestSlowReceive(
);
//
// QuicDrill tests
//
@ -805,4 +809,7 @@ typedef struct {
#define IOCTL_QUIC_RUN_KEY_UPDATE_RANDOM_LOSS \
QUIC_CTL_CODE(64, METHOD_BUFFERED, FILE_WRITE_DATA)
#define QUIC_MAX_IOCTL_FUNC_CODE 64
#define IOCTL_QUIC_RUN_SLOW_RECEIVE \
QUIC_CTL_CODE(65, METHOD_BUFFERED, FILE_WRITE_DATA)
#define QUIC_MAX_IOCTL_FUNC_CODE 65

Просмотреть файл

@ -1318,6 +1318,15 @@ TEST(Misc, AbortIncompleteReceive) {
}
}
TEST(Misc, SlowReceive) {
TestLogger Logger("SlowReceive");
if (TestingKernelMode) {
ASSERT_TRUE(DriverClient.Run(IOCTL_QUIC_RUN_SLOW_RECEIVE));
} else {
QuicTestSlowReceive();
}
}
TEST(Drill, VarIntEncoder) {
TestLogger Logger("QuicDrillTestVarIntEncoder");
if (TestingKernelMode) {

Просмотреть файл

@ -433,7 +433,8 @@ size_t QUIC_IOCTL_BUFFER_SIZES[] =
sizeof(QUIC_RUN_CRED_VALIDATION),
sizeof(QUIC_RUN_CRED_VALIDATION),
sizeof(QUIC_ABORT_RECEIVE_TYPE),
sizeof(QUIC_RUN_KEY_UPDATE_RANDOM_LOSS_PARAMS)
sizeof(QUIC_RUN_KEY_UPDATE_RANDOM_LOSS_PARAMS),
0
};
CXPLAT_STATIC_ASSERT(
@ -1029,6 +1030,11 @@ QuicTestCtlEvtIoDeviceControl(
Params->KeyUpdateRandomLossParams.Family,
Params->KeyUpdateRandomLossParams.RandomLossPercentage))
break;
case IOCTL_QUIC_RUN_SLOW_RECEIVE:
QuicTestCtlRun(QuicTestSlowReceive());
break;
default:
Status = STATUS_NOT_IMPLEMENTED;
break;

Просмотреть файл

@ -2149,3 +2149,93 @@ QuicTestAbortReceive(
TEST_QUIC_SUCCEEDED(RecvContext.ServerStream->Shutdown(1));
TEST_TRUE(RecvContext.ServerStreamShutdown.WaitTimeout(TestWaitTimeout));
}
struct SlowRecvTestContext {
CxPlatEvent ServerStreamRecv;
CxPlatEvent ServerStreamShutdown;
MsQuicStream* ServerStream {nullptr};
bool ServerStreamHasShutdown {false};
static QUIC_STATUS StreamCallback(_In_ MsQuicStream* Stream, _In_opt_ void* Context, _Inout_ QUIC_STREAM_EVENT* Event) {
auto TestContext = (SlowRecvTestContext*)Context;
if (Event->Type == QUIC_STREAM_EVENT_RECEIVE) {
TestContext->ServerStreamRecv.Set();
return QUIC_STATUS_PENDING;
} else if (Event->Type == QUIC_STREAM_EVENT_SHUTDOWN_COMPLETE) {
TestContext->ServerStreamHasShutdown = true;
TestContext->ServerStreamShutdown.Set();
Stream->ConnectionShutdown(1);
}
return QUIC_STATUS_SUCCESS;
}
static QUIC_STATUS ConnCallback(_In_ MsQuicConnection*, _In_opt_ void* Context, _Inout_ QUIC_CONNECTION_EVENT* Event) {
auto TestContext = (SlowRecvTestContext*)Context;
if (Event->Type == QUIC_CONNECTION_EVENT_PEER_STREAM_STARTED) {
TestContext->ServerStream = new MsQuicStream(Event->PEER_STREAM_STARTED.Stream, CleanUpAutoDelete, StreamCallback, Context);
}
return QUIC_STATUS_SUCCESS;
}
};
void
QuicTestSlowReceive(
void
)
{
MsQuicRegistration Registration;
TEST_QUIC_SUCCEEDED(Registration.GetInitStatus());
MsQuicConfiguration ServerConfiguration(Registration, "MsQuicTest", MsQuicSettings().SetPeerUnidiStreamCount(1), ServerSelfSignedCredConfig);
TEST_QUIC_SUCCEEDED(ServerConfiguration.GetInitStatus());
MsQuicConfiguration ClientConfiguration(Registration, "MsQuicTest", MsQuicCredentialConfig());
TEST_QUIC_SUCCEEDED(ClientConfiguration.GetInitStatus());
SlowRecvTestContext Context;
MsQuicAutoAcceptListener Listener(Registration, ServerConfiguration, SlowRecvTestContext::ConnCallback, &Context);
TEST_QUIC_SUCCEEDED(Listener.GetInitStatus());
TEST_QUIC_SUCCEEDED(Listener.Start("MsQuicTest"));
QuicAddr ServerLocalAddr;
TEST_QUIC_SUCCEEDED(Listener.GetLocalAddr(ServerLocalAddr));
MsQuicConnection Connection(Registration);
TEST_QUIC_SUCCEEDED(Connection.GetInitStatus());
TEST_QUIC_SUCCEEDED(Connection.StartLocalhost(ClientConfiguration, ServerLocalAddr));
MsQuicStream Stream(Connection, QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL);
TEST_QUIC_SUCCEEDED(Stream.GetInitStatus());
//
// Open a stream, send some data and a FIN.
//
uint8_t RawBuffer[100];
QUIC_BUFFER Buffer { sizeof(RawBuffer), RawBuffer };
TEST_QUIC_SUCCEEDED(Stream.Send(&Buffer, 1, QUIC_SEND_FLAG_START | QUIC_SEND_FLAG_FIN));
//
// Wait for the first received data on the server side. The handler always
// returns pending, so make sure that pending is respected (no shutdown).
//
TEST_TRUE(Context.ServerStreamRecv.WaitTimeout(TestWaitTimeout));
CxPlatSleep(50);
TEST_FALSE(Context.ServerStreamHasShutdown);
//
// Complete the receive and drain only the first half of the data, and then
// repeat the steps above to make sure we get another receive and it doesn't
// shutdown the stream.
//
TEST_QUIC_SUCCEEDED(Context.ServerStream->ReceiveComplete(50));
TEST_QUIC_SUCCEEDED(Context.ServerStream->ReceiveSetEnabled()); // Need to reenable because the partial receive completion pauses additional events.
TEST_TRUE(Context.ServerStreamRecv.WaitTimeout(TestWaitTimeout));
CxPlatSleep(50);
TEST_FALSE(Context.ServerStreamHasShutdown);
//
// Receive the rest of the data and make sure the shutdown is then delivered.
//
TEST_QUIC_SUCCEEDED(Context.ServerStream->ReceiveComplete(50));
TEST_TRUE(Context.ServerStreamShutdown.WaitTimeout(TestWaitTimeout));
TEST_TRUE(Context.ServerStreamHasShutdown);
}