[client/idd] network: allow unencrypted 1-RTT payloads

Expose the insecure MsQuic draft API and add an opt-in setting on both
peers. Query the negotiated state after connection establishment so
one-sided opt-in remains encrypted and is logged accurately.
This commit is contained in:
Geoffrey McRae
2026-11-06 19:28:18 +11:00
parent ea24c288ad
commit 8bbf9c3056
9 changed files with 166 additions and 44 deletions

View File

@@ -5695,10 +5695,26 @@ retry:
ResetEvent(owner.drainedEvent);
}
owner.api->SetCallbackHandler(event->NEW_CONNECTION.Connection,
reinterpret_cast<void *>(ConnectionCallback), connection);
const QUIC_STATUS status = owner.api->ConnectionSetConfiguration(
event->NEW_CONNECTION.Connection, owner.configuration);
QUIC_STATUS status = QUIC_STATUS_SUCCESS;
if (owner.settings.allowUnencrypted)
{
const BOOLEAN disableEncryption = TRUE;
status = owner.api->SetParam(event->NEW_CONNECTION.Connection,
QUIC_PARAM_CONN_DISABLE_1RTT_ENCRYPTION,
sizeof(disableEncryption), &disableEncryption);
if (QUIC_FAILED(status))
DEBUG_ERROR("Failed to allow unencrypted 1-RTT payloads for "
"network client %u: 0x%x", connection->client,
static_cast<unsigned>(status));
}
if (QUIC_SUCCEEDED(status))
{
owner.api->SetCallbackHandler(event->NEW_CONNECTION.Connection,
reinterpret_cast<void *>(ConnectionCallback), connection);
status = owner.api->ConnectionSetConfiguration(
event->NEW_CONNECTION.Connection, owner.configuration);
}
if (QUIC_FAILED(status))
{
{
@@ -5723,8 +5739,28 @@ retry:
switch (event->Type)
{
case QUIC_CONNECTION_EVENT_CONNECTED:
DEBUG_INFO("Network client %u connected", connection.client);
{
BOOLEAN encryptionDisabled = FALSE;
uint32_t encryptionDisabledLength = sizeof(encryptionDisabled);
const QUIC_STATUS status = owner.api->GetParam(handle,
QUIC_PARAM_CONN_DISABLE_1RTT_ENCRYPTION,
&encryptionDisabledLength, &encryptionDisabled);
if (QUIC_FAILED(status))
{
DEBUG_ERROR("Failed to query 1-RTT encryption for network "
"client %u: 0x%x", connection.client,
static_cast<unsigned>(status));
owner.Shutdown(connection, NETWORK_ERROR_PROTOCOL);
return QUIC_STATUS_SUCCESS;
}
DEBUG_INFO("Network client %u connected in %s mode "
"(%s 1-RTT payloads)",
connection.client,
encryptionDisabled ? "insecure" : "secure",
encryptionDisabled ? "unencrypted" : "encrypted");
return QUIC_STATUS_SUCCESS;
}
case QUIC_CONNECTION_EVENT_PEER_STREAM_STARTED:
{

View File

@@ -29,13 +29,14 @@ namespace
{
enum Field : unsigned
{
FIELD_BIND = 1U << 0,
FIELD_PORT = 1U << 1,
FIELD_MAX_CLIENTS = 1U << 2,
FIELD_AUTH = 1U << 3,
FIELD_PASSWORD = 1U << 4,
FIELD_VIDEO_CHROMA = 1U << 5,
FIELD_VIDEO_BITRATE = 1U << 6,
FIELD_BIND = 1U << 0,
FIELD_PORT = 1U << 1,
FIELD_MAX_CLIENTS = 1U << 2,
FIELD_AUTH = 1U << 3,
FIELD_PASSWORD = 1U << 4,
FIELD_VIDEO_CHROMA = 1U << 5,
FIELD_VIDEO_BITRATE = 1U << 6,
FIELD_ALLOW_UNENCRYPTED = 1U << 7,
};
std::wstring Trim(const std::wstring& value)
@@ -93,6 +94,23 @@ namespace
return true;
}
bool ParseBoolean(const std::wstring& value, bool& result)
{
if (Equal(value, L"true") || Equal(value, L"yes") ||
Equal(value, L"1"))
{
result = true;
return true;
}
if (Equal(value, L"false") || Equal(value, L"no") ||
Equal(value, L"0"))
{
result = false;
return true;
}
return false;
}
bool SetField(const std::wstring& key, const std::wstring& rawValue,
NetworkSettings& settings, unsigned& fields,
std::wstring * error)
@@ -139,6 +157,12 @@ namespace
return Fail(error, L"invalid password");
settings.password = value;
}
else if (Equal(key, L"allowUnencrypted"))
{
field = FIELD_ALLOW_UNENCRYPTED;
if (!ParseBoolean(value, settings.allowUnencrypted))
return Fail(error, L"invalid allowUnencrypted value");
}
else if (Equal(key, L"videoChroma"))
{
field = FIELD_VIDEO_CHROMA;

View File

@@ -40,6 +40,7 @@ struct NetworkSettings
uint16_t maxClients = NETWORK_DEFAULT_MAX_CLIENTS;
LGNetAuthMode auth = LG_NET_AUTH_MODE_DEFAULT;
std::wstring password;
bool allowUnencrypted = false;
uint32_t videoBitrateMbps =
NETWORK_DEFAULT_VIDEO_BITRATE_MBPS;
LGNetVideoChromaSubsampling videoChroma =
@@ -47,10 +48,11 @@ struct NetworkSettings
};
// Settings use a semicolon-separated key=value list. Supported keys are
// bind, port, maxClients, auth, password, videoBitrateMbps, and videoChroma.
// videoBitrateMbps uses decimal Mbit/s and defaults to 200. videoChroma accepts
// 420 or 444 and defaults to 444. Password authentication requires a non-empty
// password. The default address requests a dual-stack wildcard listener from
// the eventual QUIC provider.
// bind, port, maxClients, auth, password, allowUnencrypted, videoBitrateMbps,
// and videoChroma. allowUnencrypted accepts true, false, yes, no, 1, or 0 and
// defaults to false. videoBitrateMbps uses decimal Mbit/s and defaults to 200.
// videoChroma accepts 420 or 444 and defaults to 444. Password authentication
// requires a non-empty password. The default address requests a dual-stack
// wildcard listener from the eventual QUIC provider.
bool ParseNetworkSettings(const std::wstring& source,
NetworkSettings& settings, std::wstring * error = nullptr);