QUIC features
- All packets are encrypted and handshake is authenticated by using TLS 1.3.
- Parallel streams of reliable and unreliable application data.
- Exchange application data in the first round trip (0-RTT).
- Improved congestion control and loss recovery.
- Survives a change in the client’s IP address or port.
- Stateless load balancing.
- Easily extendable for new features and extensions.
MsQuic implementation
In addition to being tailored for use with GDK titles, MsQuic has several features that differentiate it from other QUIC implementations:- Optimized for client and server.
- Optimized for maximal throughput and minimal latency.
- Asynchronous IO.
- Receive side scaling (RSS) support.
- UDP sends and receives coalescing support.
Acquiring MsQuic
Microsoft hosts MsQuic in an open source GitHub repository. You should acquire MsQuic through one of its official releases located here. XBOX Series X|S console support was added in prerelease/1.9, although we recommend that you take the latest official release version when possible for GDK titles. You can find prebuilt MsQuic binaries for a given release under the Assets section for a particular release. All build flavors for a particular version of MsQuic are fully compatible with one another. While MsQuic also tries to maintain backward compatibility for their releases, refer to the MsQuic documentation and release notes for any compatibility expectations among different versions.GDK-based PC titles
Use themsquic_windows_x64_Release_openssl prebuilt binary for GDK-based PC titles.
GDK titles on PC run as native x64 Win32 applications. Use the version of MsQuic built for the x64 platform. On PC, use the version of MsQuic built with OpenSSL as it supports all OS versions that the GDK supports. The version that uses Schannel only supports the Windows 11 OS and later.
GDK-based console titles
Use themsquic_gamecore_console_x64_Release_schannel prebuilt binary for GDK-based console titles.
MsQuic provides a special build flavor for GDK-based titles on XBOX consoles. This flavor restricts MsQuic to the APIs under the WINAPI_PARTITION_GAMES and causes MsQuic to link against the XGamePlatform.lib. To consume this build flavor, you must install the XGDK from the October 2021 release or later. MsQuic uses Schannel when building for GDK-based console titles.
Client and server authentication
MsQuic automatically utilizes the same authentication and verification paths as used for HTTPS web requests in order to authenticate your server. Client authentication should follow the best practices outlined in best practices for secure client/server communication (NDA topic). In MsQuic, on both the client and server you should use the ConfigurationLoadCredential API with an appropriate QUIC_CREDENTIAL_CONFIG in order to configure your certificates. All cipher suites included by default in MsQuic are considered secure, but it’s important to properly setup how MsQuic validates the certificates on both the client and server to ensure a secure and authenticated communication channel is established. On the server, in order to use XSTS token client authentication, you should specify theQUIC_CREDENTIAL_FLAG_REQUIRE_CLIENT_AUTHENTICATION, QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED, and QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION flags. When you specify the QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION flag, you must validate the client certificate yourself within the QUIC_CONNECTION_EVENT_PEER_CERTIFICATE_RECEIVED event callback as described in the best practices for secure client/server communication (NDA topic) section.
Furthermore on the server, you should provide a properly rooted certificate in order to allow the client to authenticate your server just as you would in an HTTPS web server.
On the client, you should never specify the QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION flag, as the default MsQuic behavior for server authentication is the easiest and most secure way to validate identity. Instead, for XSTS token client authentication you should specify the QUIC_CREDENTIAL_FLAG_CLIENT flag along with the certificate generated by your server as described in the best practices for secure client/server communication (NDA topic) section. We recommend supplying the client certificate by specifying the QUIC_CREDENTIAL_TYPE_CERTIFICATE_CONTEXT mode and using APIs such as CertCreateContext to generate the context directly from your web request response data.
Network initialization
MsQuic doesn’t automatically handle network initialization for GDK titles. Wait for the network to become initialized after your title is launched and after each resume before initializing MsQuic by using MsQuicOpenVersion or MsQuicOpen.Suspend and resume
Register for suspend and resume events by usingRegisterAppStateChangeNotification. On suspend, close any open streams, and close MsQuic. Then, on resume, wait for network initialization, and then reopen MsQuic.
To close all MsQuic streams quickly within the suspend timeout, for each open stream, call StreamShutdown with the QUIC_STREAM_SHUTDOWN_FLAG_ABORT and QUIC_STREAM_SHUTDOWN_FLAG_IMMEDIATE flags. This call immediately triggers a QUIC_STREAM_EVENT_SHUTDOWN_COMPLETE event. At this point, it’s safe to call StreamClose to close the stream. Once all streams are closed for a given connection, call ConnectionShutdown with the QUIC_CONNECTION_SHUTDOWN_FLAG_SILENT flag, followed by ConnectionClose. After you close all connections, call RegistrationClose and ConfigurationClose for any outstanding registrations and configurations, followed by MsQuicClose.
Preferred port
Use the preferred local UDP multiplayer port for the main game traffic in GDK titles. Set this port in MsQuic by using the SetParam function with theQUIC_PARAM_CONN_LOCAL_ADDRESS setting on a connection object handle before calling ConnectionStart.
When you set the QUIC_PARAM_CONN_LOCAL_ADDRESS, specify the AF_UNSPEC family to allow for dual-stack IPv4 and IPv6 sockets. The following example shows how to set the preferred port when MsQuicCallTable is returned from MsQuicOpen and MsQuicConnectionHandle is returned from ConnectionOpen.
