Skip to content

OOB Connection Feature #4644

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/core/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,36 @@
return Status;
}

_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicConnCreateOOB(
_In_ QUIC_REGISTRATION* Registration,
_Inout_ uint32_t* BufferLength,
_Out_writes_bytes_opt_(*BufferLength)
void* Buffer
)
{
UNREFERENCED_PARAMETER(Registration);
UNREFERENCED_PARAMETER(BufferLength);
UNREFERENCED_PARAMETER(Buffer);
return QUIC_STATUS_NOT_SUPPORTED;
}

_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicConnSetOOB(
_In_ QUIC_CONNECTION* Connection,
_In_ uint32_t BufferLength,
_In_reads_bytes_(BufferLength)
const void* Buffer
)
{

Check warning on line 332 in src/core/connection.c

View check run for this annotation

Codecov / codecov/patch

src/core/connection.c#L332

Added line #L332 was not covered by tests
UNREFERENCED_PARAMETER(Connection);
UNREFERENCED_PARAMETER(BufferLength);
UNREFERENCED_PARAMETER(Buffer);
return QUIC_STATUS_NOT_SUPPORTED;
}

Check warning on line 337 in src/core/connection.c

View check run for this annotation

Codecov / codecov/patch

src/core/connection.c#L336-L337

Added lines #L336 - L337 were not covered by tests

_IRQL_requires_max_(DISPATCH_LEVEL)
void
QuicConnFree(
Expand Down Expand Up @@ -6614,6 +6644,10 @@
return QUIC_STATUS_SUCCESS;
}

case QUIC_PARAM_CONN_OOB_INFO:
Status = QuicConnSetOOB(Connection, BufferLength, Buffer);
break;

Check warning on line 6649 in src/core/connection.c

View check run for this annotation

Codecov / codecov/patch

src/core/connection.c#L6648-L6649

Added lines #L6648 - L6649 were not covered by tests

//
// Private
//
Expand Down
14 changes: 14 additions & 0 deletions src/core/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,20 @@ QuicConnAlloc(
QUIC_CONNECTION** NewConnection
);

//
// Creates a new (server side) out-of-band connection and writes the info to the
// output buffer for the peer (client) may use it to create an outgoing
// connection.
//
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicConnCreateOOB(
_In_ QUIC_REGISTRATION* Registration,
_Inout_ uint32_t* BufferLength,
_Out_writes_bytes_opt_(*BufferLength)
void* Buffer
);

//
// Called to free the memory for a connection.
//
Expand Down
5 changes: 5 additions & 0 deletions src/core/listener.c
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,11 @@ QuicListenerParamGet(
Status = QUIC_STATUS_SUCCESS;
break;

case QUIC_PARAM_LISTENER_OOB_CONNECTION:
Status =
QuicConnCreateOOB(Listener->Registration, BufferLength, Buffer);
break;

default:
Status = QUIC_STATUS_INVALID_PARAMETER;
break;
Expand Down
4 changes: 4 additions & 0 deletions src/inc/msquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,7 @@ typedef struct QUIC_SCHANNEL_CREDENTIAL_ATTRIBUTE_W {
#define QUIC_PARAM_LISTENER_STATS 0x04000001 // QUIC_LISTENER_STATISTICS
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
#define QUIC_PARAM_LISTENER_CIBIR_ID 0x04000002 // uint8_t[] {offset, id[]}
#define QUIC_PARAM_LISTENER_OOB_CONNECTION 0x04000003 // uint8_t[]
#endif

//
Expand Down Expand Up @@ -918,6 +919,9 @@ typedef struct QUIC_SCHANNEL_CREDENTIAL_ATTRIBUTE_W {
#define QUIC_PARAM_CONN_STATISTICS_V2 0x05000016 // QUIC_STATISTICS_V2
#define QUIC_PARAM_CONN_STATISTICS_V2_PLAT 0x05000017 // QUIC_STATISTICS_V2
#define QUIC_PARAM_CONN_ORIG_DEST_CID 0x05000018 // uint8_t[]
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
#define QUIC_PARAM_CONN_OOB_INFO 0x05000019 // uint8_t[]
#endif

//
// Parameters for TLS.
Expand Down
13 changes: 12 additions & 1 deletion src/test/MsQuicTests.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,13 @@ QuicTestShutdownDuringHandshake(
_In_ bool ClientShutdown
);

#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
void
QuicTestOOBHandshake(
_In_ int Family
);
#endif

//
// Negative Handshake Tests
//
Expand Down Expand Up @@ -1330,4 +1337,8 @@ typedef struct {
QUIC_CTL_CODE(125, METHOD_BUFFERED, FILE_WRITE_DATA)
// BOOLEAN - EnableResumption

#define QUIC_MAX_IOCTL_FUNC_CODE 125
#define IOCTL_QUIC_RUN_OOB_HANDSHAKE \
QUIC_CTL_CODE(126, METHOD_BUFFERED, FILE_WRITE_DATA)
// int - Family

#define QUIC_MAX_IOCTL_FUNC_CODE 126
11 changes: 11 additions & 0 deletions src/test/bin/quic_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,17 @@ TEST_P(WithHandshakeArgs4, RandomLossResumeRejection) {
#endif // QUIC_DISABLE_RESUMPTION
#endif // QUIC_TEST_DATAPATH_HOOKS_ENABLED

#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
TEST_P(WithFamilyArgs, OOBHandshake) {
TestLoggerT<ParamType> Logger("QuicTestOOBHandshake", GetParam());
if (TestingKernelMode) {
ASSERT_TRUE(DriverClient.Run(IOCTL_QUIC_RUN_OOB_HANDSHAKE, GetParam().Family));
} else {
QuicTestOOBHandshake(GetParam().Family);
}
}
#endif

TEST_P(WithFamilyArgs, Unreachable) {
if (GetParam().Family == 4 && IsWindows2019()) GTEST_SKIP(); // IPv4 unreachable doesn't work on 2019
TestLoggerT<ParamType> Logger("QuicTestConnectUnreachable", GetParam());
Expand Down
6 changes: 6 additions & 0 deletions src/test/bin/winkernel/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,7 @@ size_t QUIC_IOCTL_BUFFER_SIZES[] =
0,
0,
sizeof(BOOLEAN),
sizeof(INT32),
};

CXPLAT_STATIC_ASSERT(
Expand Down Expand Up @@ -1483,6 +1484,11 @@ QuicTestCtlEvtIoDeviceControl(
QuicTestCtlRun(QuicTestTlsHandshakeInfo(Params->EnableResumption != 0));
break;

case IOCTL_QUIC_RUN_OOB_HANDSHAKE:
CXPLAT_FRE_ASSERT(Params != nullptr);
QuicTestCtlRun(QuicTestOOBHandshake(Params->Family));
break;

default:
Status = STATUS_NOT_IMPLEMENTED;
break;
Expand Down
38 changes: 38 additions & 0 deletions src/test/lib/HandshakeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4023,3 +4023,41 @@ QuicTestHandshakeSpecificLossPatterns(
Listener.LastConnection->Shutdown(0, QUIC_CONNECTION_SHUTDOWN_FLAG_SILENT);
}
}

void
QuicTestOOBHandshake(
_In_ int Family
)
{
MsQuicRegistration Registration;
TEST_QUIC_SUCCEEDED(Registration.GetInitStatus());

MsQuicSettings Settings;
Settings.SetIdleTimeoutMs(60000)
.SetDisconnectTimeoutMs(60000)
.SetInitialRttMs(20);

MsQuicConfiguration ServerConfiguration(Registration, "MsQuicTest", Settings, ServerSelfSignedCredConfig);
TEST_QUIC_SUCCEEDED(ServerConfiguration.GetInitStatus());

MsQuicConfiguration ClientConfiguration(Registration, "MsQuicTest", Settings, MsQuicCredentialConfig());
TEST_QUIC_SUCCEEDED(ClientConfiguration.GetInitStatus());

QuicAddr ServerLocalAddr((Family == 4) ? QUIC_ADDRESS_FAMILY_INET : QUIC_ADDRESS_FAMILY_INET6);
MsQuicAutoAcceptListener Listener(Registration, ServerConfiguration, MsQuicConnection::NoOpCallback);
TEST_QUIC_SUCCEEDED(Listener.Start("MsQuicTest", &ServerLocalAddr.SockAddr));
TEST_QUIC_SUCCEEDED(Listener.GetInitStatus());
TEST_QUIC_SUCCEEDED(Listener.GetLocalAddr(ServerLocalAddr));

uint32_t OOBLength = 0;
TEST_QUIC_SUCCEEDED(Listener.GetParam(QUIC_PARAM_LISTENER_OOB_CONNECTION, &OOBLength, nullptr));
UniquePtr<uint8_t[]> OOBData(new(std::nothrow) uint8_t[OOBLength]);
TEST_QUIC_SUCCEEDED(Listener.GetParam(QUIC_PARAM_LISTENER_OOB_CONNECTION, &OOBLength, OOBData.get()));

MsQuicConnection Connection(Registration);
TEST_QUIC_SUCCEEDED(Connection.GetInitStatus());
TEST_QUIC_SUCCEEDED(Connection.SetParam(QUIC_PARAM_CONN_OOB_INFO, OOBLength, OOBData.get()));
TEST_QUIC_SUCCEEDED(Connection.Start(ClientConfiguration, ServerLocalAddr.GetFamily(), QUIC_TEST_LOOPBACK_FOR_AF(ServerLocalAddr.GetFamily()), ServerLocalAddr.GetPort()));
TEST_TRUE(Connection.HandshakeCompleteEvent.WaitTimeout(TestWaitTimeout));
TEST_TRUE(Connection.HandshakeComplete);
}
Loading