/*++ Copyright (c) Microsoft Corporation. Licensed under the MIT License. Abstract: Declarations for the MsQuic API, which enables applications and drivers to create QUIC connections as a client or server. For more detailed information, see ../docs/API.md Supported Platforms: Windows User mode Windows Kernel mode Linux User mode --*/ #ifndef _MSQUIC_ #define _MSQUIC_ #ifdef _WIN32 #pragma once #endif #pragma warning(disable:4201) // nonstandard extension used: nameless struct/union #pragma warning(disable:4214) // nonstandard extension used: bit field types other than int #ifdef _KERNEL_MODE #include "msquic_winkernel.h" #elif _WIN32 #include "msquic_winuser.h" #elif __linux__ || __APPLE__ || __FreeBSD__ #include "msquic_posix.h" #else #error "Unsupported Platform" #endif #if defined(__cplusplus) extern "C" { #endif typedef struct QUIC_HANDLE *HQUIC; // // The maximum value that can be encoded in a 62-bit integer. // #define QUIC_UINT62_MAX ((1ULL << 62U) - 1) // // Represents a 62-bit integer. // typedef _In_range_(0, QUIC_UINT62_MAX) uint64_t QUIC_UINT62; // // An ALPN must not exceed 255 bytes, and must not be zero-length. // #define QUIC_MAX_ALPN_LENGTH 255 // // A server name must not exceed 65535 bytes. // #define QUIC_MAX_SNI_LENGTH 65535 // // The maximum number of bytes of application data a server application can // send in a resumption ticket. // #define QUIC_MAX_RESUMPTION_APP_DATA_LENGTH 1000 typedef enum QUIC_TLS_PROVIDER { QUIC_TLS_PROVIDER_SCHANNEL = 0x0000, QUIC_TLS_PROVIDER_OPENSSL = 0x0001, } QUIC_TLS_PROVIDER; typedef enum QUIC_EXECUTION_PROFILE { QUIC_EXECUTION_PROFILE_LOW_LATENCY, // Default QUIC_EXECUTION_PROFILE_TYPE_MAX_THROUGHPUT, QUIC_EXECUTION_PROFILE_TYPE_SCAVENGER, QUIC_EXECUTION_PROFILE_TYPE_REAL_TIME, } QUIC_EXECUTION_PROFILE; typedef enum QUIC_LOAD_BALANCING_MODE { QUIC_LOAD_BALANCING_DISABLED, // Default QUIC_LOAD_BALANCING_SERVER_ID_IP, // Encodes IP address in Server ID QUIC_LOAD_BALANCING_SERVER_ID_FIXED, // Encodes a fixed 4-byte value in Server ID QUIC_LOAD_BALANCING_COUNT, // The number of supported load balancing modes // MUST BE LAST } QUIC_LOAD_BALANCING_MODE; typedef enum QUIC_TLS_ALERT_CODES { QUIC_TLS_ALERT_CODE_SUCCESS = 0xFFFF, // Not a real TlsAlert QUIC_TLS_ALERT_CODE_UNEXPECTED_MESSAGE = 10, QUIC_TLS_ALERT_CODE_BAD_CERTIFICATE = 42, QUIC_TLS_ALERT_CODE_UNSUPPORTED_CERTIFICATE = 43, QUIC_TLS_ALERT_CODE_CERTIFICATE_REVOKED = 44, QUIC_TLS_ALERT_CODE_CERTIFICATE_EXPIRED = 45, QUIC_TLS_ALERT_CODE_CERTIFICATE_UNKNOWN = 46, QUIC_TLS_ALERT_CODE_ILLEGAL_PARAMETER = 47, QUIC_TLS_ALERT_CODE_UNKNOWN_CA = 48, QUIC_TLS_ALERT_CODE_ACCESS_DENIED = 49, QUIC_TLS_ALERT_CODE_INSUFFICIENT_SECURITY = 71, QUIC_TLS_ALERT_CODE_INTERNAL_ERROR = 80, QUIC_TLS_ALERT_CODE_USER_CANCELED = 90, QUIC_TLS_ALERT_CODE_CERTIFICATE_REQUIRED = 116, QUIC_TLS_ALERT_CODE_MAX = 255, } QUIC_TLS_ALERT_CODES; typedef enum QUIC_CREDENTIAL_TYPE { QUIC_CREDENTIAL_TYPE_NONE, QUIC_CREDENTIAL_TYPE_CERTIFICATE_HASH, QUIC_CREDENTIAL_TYPE_CERTIFICATE_HASH_STORE, QUIC_CREDENTIAL_TYPE_CERTIFICATE_CONTEXT, QUIC_CREDENTIAL_TYPE_CERTIFICATE_FILE, QUIC_CREDENTIAL_TYPE_CERTIFICATE_FILE_PROTECTED, QUIC_CREDENTIAL_TYPE_CERTIFICATE_PKCS12, } QUIC_CREDENTIAL_TYPE; typedef enum QUIC_CREDENTIAL_FLAGS { QUIC_CREDENTIAL_FLAG_NONE = 0x00000000, QUIC_CREDENTIAL_FLAG_CLIENT = 0x00000001, // Lack of client flag indicates server. QUIC_CREDENTIAL_FLAG_LOAD_ASYNCHRONOUS = 0x00000002, QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION = 0x00000004, QUIC_CREDENTIAL_FLAG_ENABLE_OCSP = 0x00000008, // Schannel only currently QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED = 0x00000010, QUIC_CREDENTIAL_FLAG_DEFER_CERTIFICATE_VALIDATION = 0x00000020, QUIC_CREDENTIAL_FLAG_REQUIRE_CLIENT_AUTHENTICATION = 0x00000040, QUIC_CREDENTIAL_FLAG_USE_TLS_BUILTIN_CERTIFICATE_VALIDATION = 0x00000080, // OpenSSL only currently QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_END_CERT = 0x00000100, // Schannel only currently QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_CHAIN = 0x00000200, // Schannel only currently QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x00000400, // Schannel only currently QUIC_CREDENTIAL_FLAG_IGNORE_NO_REVOCATION_CHECK = 0x00000800, // Schannel only currently QUIC_CREDENTIAL_FLAG_IGNORE_REVOCATION_OFFLINE = 0x00001000, // Schannel only currently QUIC_CREDENTIAL_FLAG_SET_ALLOWED_CIPHER_SUITES = 0x00002000, QUIC_CREDENTIAL_FLAG_USE_PORTABLE_CERTIFICATES = 0x00004000, QUIC_CREDENTIAL_FLAG_USE_SUPPLIED_CREDENTIALS = 0x00008000, // Schannel only QUIC_CREDENTIAL_FLAG_USE_SYSTEM_MAPPER = 0x00010000, // Schannel only QUIC_CREDENTIAL_FLAG_CACHE_ONLY_URL_RETRIEVAL = 0x00020000, // Windows only currently QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_CACHE_ONLY = 0x00040000, // Windows only currently QUIC_CREDENTIAL_FLAG_INPROC_PEER_CERTIFICATE = 0x00080000, // Schannel only QUIC_CREDENTIAL_FLAG_SET_CA_CERTIFICATE_FILE = 0x00100000, // OpenSSL only currently } QUIC_CREDENTIAL_FLAGS; DEFINE_ENUM_FLAG_OPERATORS(QUIC_CREDENTIAL_FLAGS) typedef enum QUIC_ALLOWED_CIPHER_SUITE_FLAGS { QUIC_ALLOWED_CIPHER_SUITE_NONE = 0x0, QUIC_ALLOWED_CIPHER_SUITE_AES_128_GCM_SHA256 = 0x1, QUIC_ALLOWED_CIPHER_SUITE_AES_256_GCM_SHA384 = 0x2, QUIC_ALLOWED_CIPHER_SUITE_CHACHA20_POLY1305_SHA256 = 0x4, // Not supported on Schannel } QUIC_ALLOWED_CIPHER_SUITE_FLAGS; DEFINE_ENUM_FLAG_OPERATORS(QUIC_ALLOWED_CIPHER_SUITE_FLAGS); typedef enum QUIC_CERTIFICATE_HASH_STORE_FLAGS { QUIC_CERTIFICATE_HASH_STORE_FLAG_NONE = 0x0000, QUIC_CERTIFICATE_HASH_STORE_FLAG_MACHINE_STORE = 0x0001, } QUIC_CERTIFICATE_HASH_STORE_FLAGS; DEFINE_ENUM_FLAG_OPERATORS(QUIC_CERTIFICATE_HASH_STORE_FLAGS) typedef enum QUIC_CONNECTION_SHUTDOWN_FLAGS { QUIC_CONNECTION_SHUTDOWN_FLAG_NONE = 0x0000, QUIC_CONNECTION_SHUTDOWN_FLAG_SILENT = 0x0001, // Don't send the close frame over the network. } QUIC_CONNECTION_SHUTDOWN_FLAGS; DEFINE_ENUM_FLAG_OPERATORS(QUIC_CONNECTION_SHUTDOWN_FLAGS) typedef enum QUIC_SERVER_RESUMPTION_LEVEL { QUIC_SERVER_NO_RESUME, QUIC_SERVER_RESUME_ONLY, QUIC_SERVER_RESUME_AND_ZERORTT, } QUIC_SERVER_RESUMPTION_LEVEL; typedef enum QUIC_SEND_RESUMPTION_FLAGS { QUIC_SEND_RESUMPTION_FLAG_NONE = 0x0000, QUIC_SEND_RESUMPTION_FLAG_FINAL = 0x0001, // Free TLS state after sending this ticket. } QUIC_SEND_RESUMPTION_FLAGS; DEFINE_ENUM_FLAG_OPERATORS(QUIC_SEND_RESUMPTION_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. QUIC_STREAM_OPEN_FLAG_0_RTT = 0x0002, // The stream was opened via a 0-RTT packet. } QUIC_STREAM_OPEN_FLAGS; DEFINE_ENUM_FLAG_OPERATORS(QUIC_STREAM_OPEN_FLAGS) typedef enum QUIC_STREAM_START_FLAGS { QUIC_STREAM_START_FLAG_NONE = 0x0000, QUIC_STREAM_START_FLAG_IMMEDIATE = 0x0001, // Immediately informs peer that stream is open. QUIC_STREAM_START_FLAG_FAIL_BLOCKED = 0x0002, // Only opens the stream if flow control allows. QUIC_STREAM_START_FLAG_SHUTDOWN_ON_FAIL = 0x0004, // Shutdown the stream immediately after start failure. QUIC_STREAM_START_FLAG_INDICATE_PEER_ACCEPT = 0x0008, // Indicate PEER_ACCEPTED event if not accepted at start. } QUIC_STREAM_START_FLAGS; DEFINE_ENUM_FLAG_OPERATORS(QUIC_STREAM_START_FLAGS) typedef enum QUIC_STREAM_SHUTDOWN_FLAGS { QUIC_STREAM_SHUTDOWN_FLAG_NONE = 0x0000, QUIC_STREAM_SHUTDOWN_FLAG_GRACEFUL = 0x0001, // Cleanly closes the send path. QUIC_STREAM_SHUTDOWN_FLAG_ABORT_SEND = 0x0002, // Abruptly closes the send path. QUIC_STREAM_SHUTDOWN_FLAG_ABORT_RECEIVE = 0x0004, // Abruptly closes the receive path. QUIC_STREAM_SHUTDOWN_FLAG_ABORT = 0x0006, // Abruptly closes both send and receive paths. QUIC_STREAM_SHUTDOWN_FLAG_IMMEDIATE = 0x0008, // Immediately sends completion events to app. QUIC_STREAM_SHUTDOWN_FLAG_INLINE = 0x0010, // Process the shutdown immediately inline. Only for calls on callbacks. // WARNING: Can cause reentrant callbacks! } QUIC_STREAM_SHUTDOWN_FLAGS; DEFINE_ENUM_FLAG_OPERATORS(QUIC_STREAM_SHUTDOWN_FLAGS) typedef enum QUIC_RECEIVE_FLAGS { QUIC_RECEIVE_FLAG_NONE = 0x0000, QUIC_RECEIVE_FLAG_0_RTT = 0x0001, // Data was encrypted with 0-RTT key. QUIC_RECEIVE_FLAG_FIN = 0x0002, // FIN was included with this data. } QUIC_RECEIVE_FLAGS; DEFINE_ENUM_FLAG_OPERATORS(QUIC_RECEIVE_FLAGS) typedef enum QUIC_SEND_FLAGS { QUIC_SEND_FLAG_NONE = 0x0000, QUIC_SEND_FLAG_ALLOW_0_RTT = 0x0001, // Allows the use of encrypting with 0-RTT key. QUIC_SEND_FLAG_START = 0x0002, // Asynchronously starts the stream with the sent data. QUIC_SEND_FLAG_FIN = 0x0004, // Indicates the request is the one last sent on the stream. QUIC_SEND_FLAG_DGRAM_PRIORITY = 0x0008, // Indicates the datagram is higher priority than others. QUIC_SEND_FLAG_DELAY_SEND = 0x0010, // Indicates the send should be delayed because more will be queued soon. } QUIC_SEND_FLAGS; DEFINE_ENUM_FLAG_OPERATORS(QUIC_SEND_FLAGS) typedef enum QUIC_DATAGRAM_SEND_STATE { QUIC_DATAGRAM_SEND_UNKNOWN, // Not yet sent. QUIC_DATAGRAM_SEND_SENT, // Sent and awaiting acknowledegment QUIC_DATAGRAM_SEND_LOST_SUSPECT, // Suspected as lost, but still tracked QUIC_DATAGRAM_SEND_LOST_DISCARDED, // Lost and not longer being tracked QUIC_DATAGRAM_SEND_ACKNOWLEDGED, // Acknowledged QUIC_DATAGRAM_SEND_ACKNOWLEDGED_SPURIOUS, // Acknowledged after being suspected lost QUIC_DATAGRAM_SEND_CANCELED, // Canceled before send } QUIC_DATAGRAM_SEND_STATE; // // Helper to determine if a datagrams state is final, and no longer tracked // by MsQuic. // #define QUIC_DATAGRAM_SEND_STATE_IS_FINAL(State) \ ((State) >= QUIC_DATAGRAM_SEND_LOST_DISCARDED) typedef enum QUIC_EXECUTION_CONFIG_FLAGS { QUIC_EXECUTION_CONFIG_FLAG_NONE = 0x0000, #ifdef QUIC_API_ENABLE_PREVIEW_FEATURES QUIC_EXECUTION_CONFIG_FLAG_QTIP = 0x0001, #endif } QUIC_EXECUTION_CONFIG_FLAGS; DEFINE_ENUM_FLAG_OPERATORS(QUIC_EXECUTION_CONFIG_FLAGS) // // A custom configuration for thread execution in QUIC. // typedef struct QUIC_EXECUTION_CONFIG { QUIC_EXECUTION_CONFIG_FLAGS Flags; uint32_t PollingIdleTimeoutUs; // Time before a polling thread, with no work to do, sleeps. uint32_t ProcessorCount; _Field_size_(ProcessorCount) uint16_t ProcessorList[1]; // List of processors to use for threads. } QUIC_EXECUTION_CONFIG; #define QUIC_EXECUTION_CONFIG_MIN_SIZE \ (uint32_t)FIELD_OFFSET(QUIC_EXECUTION_CONFIG, ProcessorList) typedef struct QUIC_REGISTRATION_CONFIG { // All fields may be NULL/zero. const char* AppName; QUIC_EXECUTION_PROFILE ExecutionProfile; } QUIC_REGISTRATION_CONFIG; typedef _IRQL_requires_max_(PASSIVE_LEVEL) _Function_class_(QUIC_CREDENTIAL_LOAD_COMPLETE) void (QUIC_API QUIC_CREDENTIAL_LOAD_COMPLETE)( _In_ HQUIC Configuration, _In_opt_ void* Context, _In_ QUIC_STATUS Status ); typedef QUIC_CREDENTIAL_LOAD_COMPLETE *QUIC_CREDENTIAL_LOAD_COMPLETE_HANDLER; typedef struct QUIC_CERTIFICATE_HASH { uint8_t ShaHash[20]; } QUIC_CERTIFICATE_HASH; typedef struct QUIC_CERTIFICATE_HASH_STORE { QUIC_CERTIFICATE_HASH_STORE_FLAGS Flags; uint8_t ShaHash[20]; char StoreName[128]; } QUIC_CERTIFICATE_HASH_STORE; typedef struct QUIC_CERTIFICATE_FILE { const char *PrivateKeyFile; const char *CertificateFile; } QUIC_CERTIFICATE_FILE; typedef struct QUIC_CERTIFICATE_FILE_PROTECTED { const char *PrivateKeyFile; const char *CertificateFile; const char *PrivateKeyPassword; } QUIC_CERTIFICATE_FILE_PROTECTED; typedef struct QUIC_CERTIFICATE_PKCS12 { const uint8_t *Asn1Blob; uint32_t Asn1BlobLength; const char *PrivateKeyPassword; // Optional: used if provided. Ignored if NULL } QUIC_CERTIFICATE_PKCS12; typedef void QUIC_CERTIFICATE; // Platform specific certificate object typedef void QUIC_CERTIFICATE_CHAIN; // Platform specific certificate chain object typedef struct QUIC_CREDENTIAL_CONFIG { QUIC_CREDENTIAL_TYPE Type; QUIC_CREDENTIAL_FLAGS Flags; union { QUIC_CERTIFICATE_HASH* CertificateHash; QUIC_CERTIFICATE_HASH_STORE* CertificateHashStore; QUIC_CERTIFICATE* CertificateContext; QUIC_CERTIFICATE_FILE* CertificateFile; QUIC_CERTIFICATE_FILE_PROTECTED* CertificateFileProtected; QUIC_CERTIFICATE_PKCS12* CertificatePkcs12; }; const char* Principal; void* Reserved; // Currently unused QUIC_CREDENTIAL_LOAD_COMPLETE_HANDLER AsyncHandler; // Optional QUIC_ALLOWED_CIPHER_SUITE_FLAGS AllowedCipherSuites;// Optional const char* CaCertificateFile; // Optional } QUIC_CREDENTIAL_CONFIG; // // The maximum number of QUIC_TICKET_KEY_CONFIG that can be used at one time. // #define QUIC_MAX_TICKET_KEY_COUNT 16 // // TLS New Session Ticket encryption key configuration. // typedef struct QUIC_TICKET_KEY_CONFIG { uint8_t Id[16]; uint8_t Material[64]; uint8_t MaterialLength; } QUIC_TICKET_KEY_CONFIG; // // A single contiguous buffer. // typedef struct QUIC_BUFFER { uint32_t Length; _Field_size_bytes_(Length) uint8_t* Buffer; } QUIC_BUFFER; // // All the available information describing a new incoming connection. // typedef struct QUIC_NEW_CONNECTION_INFO { uint32_t QuicVersion; const QUIC_ADDR* LocalAddress; const QUIC_ADDR* RemoteAddress; uint32_t CryptoBufferLength; uint16_t ClientAlpnListLength; uint16_t ServerNameLength; uint8_t NegotiatedAlpnLength; _Field_size_bytes_(CryptoBufferLength) const uint8_t* CryptoBuffer; _Field_size_bytes_(ClientAlpnListLength) const uint8_t* ClientAlpnList; _Field_size_bytes_(NegotiatedAlpnLength) const uint8_t* NegotiatedAlpn; _Field_size_bytes_opt_(ServerNameLength) const char* ServerName; } QUIC_NEW_CONNECTION_INFO; typedef enum QUIC_TLS_PROTOCOL_VERSION { QUIC_TLS_PROTOCOL_UNKNOWN = 0, QUIC_TLS_PROTOCOL_1_3 = 0x3000, } QUIC_TLS_PROTOCOL_VERSION; typedef enum QUIC_CIPHER_ALGORITHM { QUIC_CIPHER_ALGORITHM_NONE = 0, QUIC_CIPHER_ALGORITHM_AES_128 = 0x660E, QUIC_CIPHER_ALGORITHM_AES_256 = 0x6610, QUIC_CIPHER_ALGORITHM_CHACHA20 = 0x6612, // Not supported on Schannel/BCrypt } QUIC_CIPHER_ALGORITHM; typedef enum QUIC_HASH_ALGORITHM { QUIC_HASH_ALGORITHM_NONE = 0, QUIC_HASH_ALGORITHM_SHA_256 = 0x800C, QUIC_HASH_ALGORITHM_SHA_384 = 0x800D, } QUIC_HASH_ALGORITHM; typedef enum QUIC_KEY_EXCHANGE_ALGORITHM { QUIC_KEY_EXCHANGE_ALGORITHM_NONE = 0, } QUIC_KEY_EXCHANGE_ALGORITHM; typedef enum QUIC_CIPHER_SUITE { QUIC_CIPHER_SUITE_TLS_AES_128_GCM_SHA256 = 0x1301, QUIC_CIPHER_SUITE_TLS_AES_256_GCM_SHA384 = 0x1302, QUIC_CIPHER_SUITE_TLS_CHACHA20_POLY1305_SHA256 = 0x1303, // Not supported on Schannel } QUIC_CIPHER_SUITE; typedef enum QUIC_CONGESTION_CONTROL_ALGORITHM { QUIC_CONGESTION_CONTROL_ALGORITHM_CUBIC, #ifdef QUIC_API_ENABLE_PREVIEW_FEATURES QUIC_CONGESTION_CONTROL_ALGORITHM_BBR, #endif QUIC_CONGESTION_CONTROL_ALGORITHM_MAX, } QUIC_CONGESTION_CONTROL_ALGORITHM; // // All the available information describing a handshake. // typedef struct QUIC_HANDSHAKE_INFO { QUIC_TLS_PROTOCOL_VERSION TlsProtocolVersion; QUIC_CIPHER_ALGORITHM CipherAlgorithm; int32_t CipherStrength; QUIC_HASH_ALGORITHM Hash; int32_t HashStrength; QUIC_KEY_EXCHANGE_ALGORITHM KeyExchangeAlgorithm; int32_t KeyExchangeStrength; QUIC_CIPHER_SUITE CipherSuite; } QUIC_HANDSHAKE_INFO; // // All statistics available to query about a connection. // typedef struct QUIC_STATISTICS { uint64_t CorrelationId; uint32_t VersionNegotiation : 1; uint32_t StatelessRetry : 1; uint32_t ResumptionAttempted : 1; uint32_t ResumptionSucceeded : 1; uint32_t Rtt; // In microseconds uint32_t MinRtt; // In microseconds uint32_t MaxRtt; // In microseconds struct { uint64_t Start; uint64_t InitialFlightEnd; // Processed all peer's Initial packets uint64_t HandshakeFlightEnd; // Processed all peer's Handshake packets } Timing; struct { uint32_t ClientFlight1Bytes; // Sum of TLS payloads uint32_t ServerFlight1Bytes; // Sum of TLS payloads uint32_t ClientFlight2Bytes; // Sum of TLS payloads } Handshake; struct { uint16_t PathMtu; // Current path MTU. uint64_t TotalPackets; // QUIC packets; could be coalesced into fewer UDP datagrams. uint64_t RetransmittablePackets; uint64_t SuspectedLostPackets; uint64_t SpuriousLostPackets; // Actual lost is (SuspectedLostPackets - SpuriousLostPackets) uint64_t TotalBytes; // Sum of UDP payloads uint64_t TotalStreamBytes; // Sum of stream payloads uint32_t CongestionCount; // Number of congestion events uint32_t PersistentCongestionCount; // Number of persistent congestion events } Send; struct { uint64_t TotalPackets; // QUIC packets; could be coalesced into fewer UDP datagrams. uint64_t ReorderedPackets; // Packets where packet number is less than highest seen. uint64_t DroppedPackets; // Includes DuplicatePackets. uint64_t DuplicatePackets; uint64_t TotalBytes; // Sum of UDP payloads uint64_t TotalStreamBytes; // Sum of stream payloads uint64_t DecryptionFailures; // Count of packet decryption failures. uint64_t ValidAckFrames; // Count of receive ACK frames. } Recv; struct { uint32_t KeyUpdateCount; } Misc; } QUIC_STATISTICS; // // N.B. Consumers of this struct depend on it being the same for 32-bit and // 64-bit systems. DO NOT include any fields that have different sizes on those // platforms, such as size_t or pointers. // typedef struct QUIC_STATISTICS_V2 { uint64_t CorrelationId; uint32_t VersionNegotiation : 1; uint32_t StatelessRetry : 1; uint32_t ResumptionAttempted : 1; uint32_t ResumptionSucceeded : 1; uint32_t GreaseBitNegotiated : 1; // Set if we negotiated the GREASE bit. uint32_t EcnCapable : 1; uint32_t RESERVED : 26; uint32_t Rtt; // In microseconds uint32_t MinRtt; // In microseconds uint32_t MaxRtt; // In microseconds uint64_t TimingStart; uint64_t TimingInitialFlightEnd; // Processed all peer's Initial packets uint64_t TimingHandshakeFlightEnd; // Processed all peer's Handshake packets uint32_t HandshakeClientFlight1Bytes; // Sum of TLS payloads uint32_t HandshakeServerFlight1Bytes; // Sum of TLS payloads uint32_t HandshakeClientFlight2Bytes; // Sum of TLS payloads uint16_t SendPathMtu; // Current path MTU. uint64_t SendTotalPackets; // QUIC packets; could be coalesced into fewer UDP datagrams. uint64_t SendRetransmittablePackets; uint64_t SendSuspectedLostPackets; uint64_t SendSpuriousLostPackets; // Actual lost is (SuspectedLostPackets - SpuriousLostPackets) uint64_t SendTotalBytes; // Sum of UDP payloads uint64_t SendTotalStreamBytes; // Sum of stream payloads uint32_t SendCongestionCount; // Number of congestion events uint32_t SendPersistentCongestionCount; // Number of persistent congestion events uint64_t RecvTotalPackets; // QUIC packets; could be coalesced into fewer UDP datagrams. uint64_t RecvReorderedPackets; // Packets where packet number is less than highest seen. uint64_t RecvDroppedPackets; // Includes DuplicatePackets. uint64_t RecvDuplicatePackets; uint64_t RecvTotalBytes; // Sum of UDP payloads uint64_t RecvTotalStreamBytes; // Sum of stream payloads uint64_t RecvDecryptionFailures; // Count of packet decryption failures. uint64_t RecvValidAckFrames; // Count of receive ACK frames. uint32_t KeyUpdateCount; uint32_t SendCongestionWindow; // Congestion window size uint32_t DestCidUpdateCount; // Number of times the destionation CID changed. uint32_t SendEcnCongestionCount; // Number of congestion events caused by ECN. // N.B. New fields must be appended to end } QUIC_STATISTICS_V2; #define QUIC_STRUCT_SIZE_THRU_FIELD(Struct, Field) \ (FIELD_OFFSET(Struct, Field) + sizeof(((Struct*)0)->Field)) #define QUIC_STATISTICS_V2_SIZE_1 QUIC_STRUCT_SIZE_THRU_FIELD(QUIC_STATISTICS_V2, KeyUpdateCount) // v2.0 final size #define QUIC_STATISTICS_V2_SIZE_2 QUIC_STRUCT_SIZE_THRU_FIELD(QUIC_STATISTICS_V2, DestCidUpdateCount) // v2.1 final size #define QUIC_STATISTICS_V2_SIZE_3 QUIC_STRUCT_SIZE_THRU_FIELD(QUIC_STATISTICS_V2, SendEcnCongestionCount) // v2.2 final size typedef struct QUIC_LISTENER_STATISTICS { uint64_t TotalAcceptedConnections; uint64_t TotalRejectedConnections; uint64_t BindingRecvDroppedPackets; } QUIC_LISTENER_STATISTICS; typedef enum QUIC_PERFORMANCE_COUNTERS { QUIC_PERF_COUNTER_CONN_CREATED, // Total connections ever allocated. QUIC_PERF_COUNTER_CONN_HANDSHAKE_FAIL, // Total connections that failed during handshake. QUIC_PERF_COUNTER_CONN_APP_REJECT, // Total connections rejected by the application. QUIC_PERF_COUNTER_CONN_RESUMED, // Total connections resumed. QUIC_PERF_COUNTER_CONN_ACTIVE, // Connections currently allocated. QUIC_PERF_COUNTER_CONN_CONNECTED, // Connections currently in the connected state. QUIC_PERF_COUNTER_CONN_PROTOCOL_ERRORS, // Total connections shutdown with a protocol error. QUIC_PERF_COUNTER_CONN_NO_ALPN, // Total connection attempts with no matching ALPN. QUIC_PERF_COUNTER_STRM_ACTIVE, // Current streams allocated. QUIC_PERF_COUNTER_PKTS_SUSPECTED_LOST, // Total suspected packets lost QUIC_PERF_COUNTER_PKTS_DROPPED, // Total packets dropped for any reason. QUIC_PERF_COUNTER_PKTS_DECRYPTION_FAIL, // Total packets with decryption failures. QUIC_PERF_COUNTER_UDP_RECV, // Total UDP datagrams received. QUIC_PERF_COUNTER_UDP_SEND, // Total UDP datagrams sent. QUIC_PERF_COUNTER_UDP_RECV_BYTES, // Total UDP payload bytes received. QUIC_PERF_COUNTER_UDP_SEND_BYTES, // Total UDP payload bytes sent. QUIC_PERF_COUNTER_UDP_RECV_EVENTS, // Total UDP receive events. QUIC_PERF_COUNTER_UDP_SEND_CALLS, // Total UDP send API calls. QUIC_PERF_COUNTER_APP_SEND_BYTES, // Total bytes sent by applications. QUIC_PERF_COUNTER_APP_RECV_BYTES, // Total bytes received by applications. QUIC_PERF_COUNTER_CONN_QUEUE_DEPTH, // Current connections queued for processing. QUIC_PERF_COUNTER_CONN_OPER_QUEUE_DEPTH,// Current connection operations queued. QUIC_PERF_COUNTER_CONN_OPER_QUEUED, // Total connection operations queued ever. QUIC_PERF_COUNTER_CONN_OPER_COMPLETED, // Total connection operations processed ever. QUIC_PERF_COUNTER_WORK_OPER_QUEUE_DEPTH,// Current worker operations queued. QUIC_PERF_COUNTER_WORK_OPER_QUEUED, // Total worker operations queued ever. QUIC_PERF_COUNTER_WORK_OPER_COMPLETED, // Total worker operations processed ever. QUIC_PERF_COUNTER_PATH_VALIDATED, // Total path challenges that succeed ever. QUIC_PERF_COUNTER_PATH_FAILURE, // Total path challenges that fail ever. QUIC_PERF_COUNTER_SEND_STATELESS_RESET, // Total stateless reset packets sent ever. QUIC_PERF_COUNTER_SEND_STATELESS_RETRY, // Total stateless retry packets sent ever. QUIC_PERF_COUNTER_MAX, } QUIC_PERFORMANCE_COUNTERS; #ifdef QUIC_API_ENABLE_PREVIEW_FEATURES typedef struct QUIC_VERSION_SETTINGS { const uint32_t* AcceptableVersions; const uint32_t* OfferedVersions; const uint32_t* FullyDeployedVersions; uint32_t AcceptableVersionsLength; uint32_t OfferedVersionsLength; uint32_t FullyDeployedVersionsLength; } QUIC_VERSION_SETTINGS; #endif typedef struct QUIC_GLOBAL_SETTINGS { union { uint64_t IsSetFlags; struct { uint64_t RetryMemoryLimit : 1; uint64_t LoadBalancingMode : 1; uint64_t FixedServerID : 1; uint64_t RESERVED : 61; } IsSet; }; uint16_t RetryMemoryLimit; uint16_t LoadBalancingMode; uint32_t FixedServerID; } QUIC_GLOBAL_SETTINGS; typedef struct QUIC_SETTINGS { union { uint64_t IsSetFlags; struct { uint64_t MaxBytesPerKey : 1; uint64_t HandshakeIdleTimeoutMs : 1; uint64_t IdleTimeoutMs : 1; uint64_t MtuDiscoverySearchCompleteTimeoutUs : 1; uint64_t TlsClientMaxSendBuffer : 1; uint64_t TlsServerMaxSendBuffer : 1; uint64_t StreamRecvWindowDefault : 1; uint64_t StreamRecvBufferDefault : 1; uint64_t ConnFlowControlWindow : 1; uint64_t MaxWorkerQueueDelayUs : 1; uint64_t MaxStatelessOperations : 1; uint64_t InitialWindowPackets : 1; uint64_t SendIdleTimeoutMs : 1; uint64_t InitialRttMs : 1; uint64_t MaxAckDelayMs : 1; uint64_t DisconnectTimeoutMs : 1; uint64_t KeepAliveIntervalMs : 1; uint64_t CongestionControlAlgorithm : 1; uint64_t PeerBidiStreamCount : 1; uint64_t PeerUnidiStreamCount : 1; uint64_t MaxBindingStatelessOperations : 1; uint64_t StatelessOperationExpirationMs : 1; uint64_t MinimumMtu : 1; uint64_t MaximumMtu : 1; uint64_t SendBufferingEnabled : 1; uint64_t PacingEnabled : 1; uint64_t MigrationEnabled : 1; uint64_t DatagramReceiveEnabled : 1; uint64_t ServerResumptionLevel : 1; uint64_t MaxOperationsPerDrain : 1; uint64_t MtuDiscoveryMissingProbeCount : 1; uint64_t DestCidUpdateIdleTimeoutMs : 1; uint64_t GreaseQuicBitEnabled : 1; uint64_t EcnEnabled : 1; uint64_t HyStartEnabled : 1; uint64_t RESERVED : 29; } IsSet; }; uint64_t MaxBytesPerKey; uint64_t HandshakeIdleTimeoutMs; uint64_t IdleTimeoutMs; uint64_t MtuDiscoverySearchCompleteTimeoutUs; uint32_t TlsClientMaxSendBuffer; uint32_t TlsServerMaxSendBuffer; uint32_t StreamRecvWindowDefault; uint32_t StreamRecvBufferDefault; uint32_t ConnFlowControlWindow; uint32_t MaxWorkerQueueDelayUs; uint32_t MaxStatelessOperations; uint32_t InitialWindowPackets; uint32_t SendIdleTimeoutMs; uint32_t InitialRttMs; uint32_t MaxAckDelayMs; uint32_t DisconnectTimeoutMs; uint32_t KeepAliveIntervalMs; uint16_t CongestionControlAlgorithm; // QUIC_CONGESTION_CONTROL_ALGORITHM uint16_t PeerBidiStreamCount; uint16_t PeerUnidiStreamCount; uint16_t MaxBindingStatelessOperations; uint16_t StatelessOperationExpirationMs; uint16_t MinimumMtu; uint16_t MaximumMtu; uint8_t SendBufferingEnabled : 1; uint8_t PacingEnabled : 1; uint8_t MigrationEnabled : 1; uint8_t DatagramReceiveEnabled : 1; uint8_t ServerResumptionLevel : 2; // QUIC_SERVER_RESUMPTION_LEVEL uint8_t GreaseQuicBitEnabled : 1; uint8_t EcnEnabled : 1; uint8_t MaxOperationsPerDrain; uint8_t MtuDiscoveryMissingProbeCount; uint32_t DestCidUpdateIdleTimeoutMs; union { uint64_t Flags; struct { uint64_t HyStartEnabled : 1; uint64_t ReservedFlags : 63; }; }; } QUIC_SETTINGS; // // This struct enables QUIC applications to support SSLKEYLOGFILE // for debugging packet captures with e.g. Wireshark. // #define QUIC_TLS_SECRETS_MAX_SECRET_LEN 64 typedef struct QUIC_TLS_SECRETS { uint8_t SecretLength; struct { uint8_t ClientRandom : 1; uint8_t ClientEarlyTrafficSecret : 1; uint8_t ClientHandshakeTrafficSecret : 1; uint8_t ServerHandshakeTrafficSecret : 1; uint8_t ClientTrafficSecret0 : 1; uint8_t ServerTrafficSecret0 : 1; } IsSet; uint8_t ClientRandom[32]; uint8_t ClientEarlyTrafficSecret[QUIC_TLS_SECRETS_MAX_SECRET_LEN]; uint8_t ClientHandshakeTrafficSecret[QUIC_TLS_SECRETS_MAX_SECRET_LEN]; uint8_t ServerHandshakeTrafficSecret[QUIC_TLS_SECRETS_MAX_SECRET_LEN]; uint8_t ClientTrafficSecret0[QUIC_TLS_SECRETS_MAX_SECRET_LEN]; uint8_t ServerTrafficSecret0[QUIC_TLS_SECRETS_MAX_SECRET_LEN]; } QUIC_TLS_SECRETS; typedef struct QUIC_STREAM_STATISTICS { uint64_t ConnBlockedBySchedulingUs; uint64_t ConnBlockedByPacingUs; uint64_t ConnBlockedByAmplificationProtUs; uint64_t ConnBlockedByCongestionControlUs; uint64_t ConnBlockedByFlowControlUs; uint64_t StreamBlockedByIdFlowControlUs; uint64_t StreamBlockedByFlowControlUs; uint64_t StreamBlockedByAppUs; } QUIC_STREAM_STATISTICS; // // Functions for associating application contexts with QUIC handles. MsQuic // provides no explicit synchronization between parallel calls to these // functions. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) void (QUIC_API * QUIC_SET_CONTEXT_FN)( _In_ _Pre_defensive_ HQUIC Handle, _In_opt_ void* Context ); typedef _IRQL_requires_max_(DISPATCH_LEVEL) void* (QUIC_API * QUIC_GET_CONTEXT_FN)( _In_ _Pre_defensive_ HQUIC Handle ); // // Sets the event handler for the QUIC handle. The type of the handler must be // appropriate for the type of the handle. MsQuic provides no explicit // synchronization between parallel calls to this function or the ones above. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) void (QUIC_API * QUIC_SET_CALLBACK_HANDLER_FN)( _In_ _Pre_defensive_ HQUIC Handle, _In_ void* Handler, _In_opt_ void* Context ); // // Get and Set parameters on a handle. // #define QUIC_PARAM_PREFIX_GLOBAL 0x01000000 #define QUIC_PARAM_PREFIX_REGISTRATION 0x02000000 #define QUIC_PARAM_PREFIX_CONFIGURATION 0x03000000 #define QUIC_PARAM_PREFIX_LISTENER 0x04000000 #define QUIC_PARAM_PREFIX_CONNECTION 0x05000000 #define QUIC_PARAM_PREFIX_TLS 0x06000000 #define QUIC_PARAM_PREFIX_TLS_SCHANNEL 0x07000000 #define QUIC_PARAM_PREFIX_STREAM 0x08000000 #define QUIC_PARAM_IS_GLOBAL(Param) ((Param & 0x7F000000) == QUIC_PARAM_PREFIX_GLOBAL) // // Parameters for Global. // #define QUIC_PARAM_GLOBAL_RETRY_MEMORY_PERCENT 0x01000000 // uint16_t #define QUIC_PARAM_GLOBAL_SUPPORTED_VERSIONS 0x01000001 // uint32_t[] - network byte order #define QUIC_PARAM_GLOBAL_LOAD_BALACING_MODE 0x01000002 // uint16_t - QUIC_LOAD_BALANCING_MODE #define QUIC_PARAM_GLOBAL_PERF_COUNTERS 0x01000003 // uint64_t[] - Array size is QUIC_PERF_COUNTER_MAX #define QUIC_PARAM_GLOBAL_LIBRARY_VERSION 0x01000004 // uint32_t[4] #define QUIC_PARAM_GLOBAL_SETTINGS 0x01000005 // QUIC_SETTINGS #define QUIC_PARAM_GLOBAL_GLOBAL_SETTINGS 0x01000006 // QUIC_GLOBAL_SETTINGS #ifdef QUIC_API_ENABLE_PREVIEW_FEATURES #define QUIC_PARAM_GLOBAL_VERSION_SETTINGS 0x01000007 // QUIC_VERSION_SETTINGS #endif #define QUIC_PARAM_GLOBAL_LIBRARY_GIT_HASH 0x01000008 // char[64] #ifdef QUIC_API_ENABLE_PREVIEW_FEATURES #define QUIC_PARAM_GLOBAL_EXECUTION_CONFIG 0x01000009 // QUIC_EXECUTION_CONFIG #endif #define QUIC_PARAM_GLOBAL_TLS_PROVIDER 0x0100000A // QUIC_TLS_PROVIDER // // Parameters for Registration. // // // Parameters for Configuration. // #define QUIC_PARAM_CONFIGURATION_SETTINGS 0x03000000 // QUIC_SETTINGS #define QUIC_PARAM_CONFIGURATION_TICKET_KEYS 0x03000001 // QUIC_TICKET_KEY_CONFIG[] #ifdef QUIC_API_ENABLE_PREVIEW_FEATURES #define QUIC_PARAM_CONFIGURATION_VERSION_SETTINGS 0x03000002 // QUIC_VERSION_SETTINGS #endif // Schannel-specific Configuration parameter typedef struct QUIC_SCHANNEL_CREDENTIAL_ATTRIBUTE_W { unsigned long Attribute; unsigned long BufferLength; void* Buffer; } QUIC_SCHANNEL_CREDENTIAL_ATTRIBUTE_W; #define QUIC_PARAM_CONFIGURATION_SCHANNEL_CREDENTIAL_ATTRIBUTE_W 0x03000003 // QUIC_SCHANNEL_CREDENTIAL_ATTRIBUTE_W // // Parameters for Listener. // #define QUIC_PARAM_LISTENER_LOCAL_ADDRESS 0x04000000 // QUIC_ADDR #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[]} #endif // // Parameters for Connection. // #define QUIC_PARAM_CONN_QUIC_VERSION 0x05000000 // uint32_t #define QUIC_PARAM_CONN_LOCAL_ADDRESS 0x05000001 // QUIC_ADDR #define QUIC_PARAM_CONN_REMOTE_ADDRESS 0x05000002 // QUIC_ADDR #define QUIC_PARAM_CONN_IDEAL_PROCESSOR 0x05000003 // uint16_t #define QUIC_PARAM_CONN_SETTINGS 0x05000004 // QUIC_SETTINGS #define QUIC_PARAM_CONN_STATISTICS 0x05000005 // QUIC_STATISTICS #define QUIC_PARAM_CONN_STATISTICS_PLAT 0x05000006 // QUIC_STATISTICS #define QUIC_PARAM_CONN_SHARE_UDP_BINDING 0x05000007 // uint8_t (BOOLEAN) #define QUIC_PARAM_CONN_LOCAL_BIDI_STREAM_COUNT 0x05000008 // uint16_t #define QUIC_PARAM_CONN_LOCAL_UNIDI_STREAM_COUNT 0x05000009 // uint16_t #define QUIC_PARAM_CONN_MAX_STREAM_IDS 0x0500000A // uint64_t[4] #define QUIC_PARAM_CONN_CLOSE_REASON_PHRASE 0x0500000B // char[] #define QUIC_PARAM_CONN_STREAM_SCHEDULING_SCHEME 0x0500000C // QUIC_STREAM_SCHEDULING_SCHEME #define QUIC_PARAM_CONN_DATAGRAM_RECEIVE_ENABLED 0x0500000D // uint8_t (BOOLEAN) #define QUIC_PARAM_CONN_DATAGRAM_SEND_ENABLED 0x0500000E // uint8_t (BOOLEAN) #ifdef QUIC_API_ENABLE_INSECURE_FEATURES #define QUIC_PARAM_CONN_DISABLE_1RTT_ENCRYPTION 0x0500000F // uint8_t (BOOLEAN) #endif #define QUIC_PARAM_CONN_RESUMPTION_TICKET 0x05000010 // uint8_t[] #define QUIC_PARAM_CONN_PEER_CERTIFICATE_VALID 0x05000011 // uint8_t (BOOLEAN) #define QUIC_PARAM_CONN_LOCAL_INTERFACE 0x05000012 // uint32_t #define QUIC_PARAM_CONN_TLS_SECRETS 0x05000013 // QUIC_TLS_SECRETS (SSLKEYLOGFILE compatible) #ifdef QUIC_API_ENABLE_PREVIEW_FEATURES #define QUIC_PARAM_CONN_VERSION_SETTINGS 0x05000014 // QUIC_VERSION_SETTINGS #define QUIC_PARAM_CONN_CIBIR_ID 0x05000015 // uint8_t[] {offset, id[]} #endif #define QUIC_PARAM_CONN_STATISTICS_V2 0x05000016 // QUIC_STATISTICS_V2 #define QUIC_PARAM_CONN_STATISTICS_V2_PLAT 0x05000017 // QUIC_STATISTICS_V2 // // Parameters for TLS. // #define QUIC_PARAM_TLS_HANDSHAKE_INFO 0x06000000 // QUIC_HANDSHAKE_INFO #define QUIC_PARAM_TLS_NEGOTIATED_ALPN 0x06000001 // uint8_t[] (max 255 bytes) #ifdef WIN32 // Schannel specific TLS parameters typedef struct QUIC_SCHANNEL_CONTEXT_ATTRIBUTE_W { unsigned long Attribute; void* Buffer; } QUIC_SCHANNEL_CONTEXT_ATTRIBUTE_W; #define QUIC_PARAM_TLS_SCHANNEL_CONTEXT_ATTRIBUTE_W 0x07000000 // QUIC_SCHANNEL_CONTEXT_ATTRIBUTE_W typedef struct QUIC_SCHANNEL_CONTEXT_ATTRIBUTE_EX_W { unsigned long Attribute; unsigned long BufferLength; void* Buffer; } QUIC_SCHANNEL_CONTEXT_ATTRIBUTE_EX_W; #define QUIC_PARAM_TLS_SCHANNEL_CONTEXT_ATTRIBUTE_EX_W 0x07000001 // QUIC_SCHANNEL_CONTEXT_ATTRIBUTE_EX_W #define QUIC_PARAM_TLS_SCHANNEL_SECURITY_CONTEXT_TOKEN 0x07000002 // HANDLE #endif // // Parameters for Stream. // #define QUIC_PARAM_STREAM_ID 0x08000000 // QUIC_UINT62 #define QUIC_PARAM_STREAM_0RTT_LENGTH 0x08000001 // uint64_t #define QUIC_PARAM_STREAM_IDEAL_SEND_BUFFER_SIZE 0x08000002 // uint64_t - bytes #define QUIC_PARAM_STREAM_PRIORITY 0x08000003 // uint16_t - 0 (low) to 0xFFFF (high) - 0x7FFF (default) #define QUIC_PARAM_STREAM_STATISTICS 0X08000004 // QUIC_STREAM_STATISTICS typedef _IRQL_requires_max_(PASSIVE_LEVEL) QUIC_STATUS (QUIC_API * QUIC_SET_PARAM_FN)( _When_(QUIC_PARAM_IS_GLOBAL(Param), _Reserved_) _When_(!QUIC_PARAM_IS_GLOBAL(Param), _In_ _Pre_defensive_) HQUIC Handle, _In_ uint32_t Param, _In_ uint32_t BufferLength, _In_reads_bytes_(BufferLength) const void* Buffer ); typedef _IRQL_requires_max_(PASSIVE_LEVEL) QUIC_STATUS (QUIC_API * QUIC_GET_PARAM_FN)( _When_(QUIC_PARAM_IS_GLOBAL(Param), _Reserved_) _When_(!QUIC_PARAM_IS_GLOBAL(Param), _In_ _Pre_defensive_) HQUIC Handle, _In_ uint32_t Param, _Inout_ _Pre_defensive_ uint32_t* BufferLength, _Out_writes_bytes_opt_(*BufferLength) void* Buffer ); // // Registration Context Interface. // // // Opens a new registration. // typedef _IRQL_requires_max_(PASSIVE_LEVEL) QUIC_STATUS (QUIC_API * QUIC_REGISTRATION_OPEN_FN)( _In_opt_ const QUIC_REGISTRATION_CONFIG* Config, _Outptr_ _At_(*Registration, __drv_allocatesMem(Mem)) _Pre_defensive_ HQUIC* Registration ); // // Closes the registration. This function synchronizes the cleanup of all // child objects. It does this by blocking until all those child objects have // been closed by the application. // N.B. This function will deadlock if called in any MsQuic callbacks. // typedef _IRQL_requires_max_(PASSIVE_LEVEL) void (QUIC_API * QUIC_REGISTRATION_CLOSE_FN)( _In_ _Pre_defensive_ __drv_freesMem(Mem) HQUIC Registration ); // // Calls shutdown for all connections in this registration. Don't call on a // MsQuic callback thread or it might deadlock. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) void (QUIC_API * QUIC_REGISTRATION_SHUTDOWN_FN)( _In_ _Pre_defensive_ HQUIC Registration, _In_ QUIC_CONNECTION_SHUTDOWN_FLAGS Flags, _In_ _Pre_defensive_ QUIC_UINT62 ErrorCode // Application defined error code ); // // Configuration Interface. // // // Opens a new configuration. // typedef _IRQL_requires_max_(PASSIVE_LEVEL) QUIC_STATUS (QUIC_API * QUIC_CONFIGURATION_OPEN_FN)( _In_ _Pre_defensive_ HQUIC Registration, _In_reads_(AlpnBufferCount) _Pre_defensive_ const QUIC_BUFFER* const AlpnBuffers, _In_range_(>, 0) uint32_t AlpnBufferCount, _In_reads_bytes_opt_(SettingsSize) const QUIC_SETTINGS* Settings, _In_ uint32_t SettingsSize, _In_opt_ void* Context, _Outptr_ _At_(*Configuration, __drv_allocatesMem(Mem)) _Pre_defensive_ HQUIC* Configuration ); // // Closes an existing configuration. // typedef _IRQL_requires_max_(PASSIVE_LEVEL) void (QUIC_API * QUIC_CONFIGURATION_CLOSE_FN)( _In_ _Pre_defensive_ __drv_freesMem(Mem) HQUIC Configuration ); // // Loads the credentials based on the input configuration. // typedef _IRQL_requires_max_(PASSIVE_LEVEL) QUIC_STATUS (QUIC_API * QUIC_CONFIGURATION_LOAD_CREDENTIAL_FN)( _In_ _Pre_defensive_ HQUIC Configuration, _In_ _Pre_defensive_ const QUIC_CREDENTIAL_CONFIG* CredConfig ); // // Listener Context Interface. // typedef enum QUIC_LISTENER_EVENT_TYPE { QUIC_LISTENER_EVENT_NEW_CONNECTION = 0, QUIC_LISTENER_EVENT_STOP_COMPLETE = 1, } QUIC_LISTENER_EVENT_TYPE; typedef struct QUIC_LISTENER_EVENT { QUIC_LISTENER_EVENT_TYPE Type; union { struct { const QUIC_NEW_CONNECTION_INFO* Info; HQUIC Connection; } NEW_CONNECTION; struct { BOOLEAN AppCloseInProgress : 1; BOOLEAN RESERVED : 7; } STOP_COMPLETE; }; } QUIC_LISTENER_EVENT; typedef _IRQL_requires_max_(PASSIVE_LEVEL) _Function_class_(QUIC_LISTENER_CALLBACK) QUIC_STATUS (QUIC_API QUIC_LISTENER_CALLBACK)( _In_ HQUIC Listener, _In_opt_ void* Context, _Inout_ QUIC_LISTENER_EVENT* Event ); typedef QUIC_LISTENER_CALLBACK *QUIC_LISTENER_CALLBACK_HANDLER; // // Opens a new listener. // typedef _IRQL_requires_max_(PASSIVE_LEVEL) QUIC_STATUS (QUIC_API * QUIC_LISTENER_OPEN_FN)( _In_ _Pre_defensive_ HQUIC Registration, _In_ _Pre_defensive_ QUIC_LISTENER_CALLBACK_HANDLER Handler, _In_opt_ void* Context, _Outptr_ _At_(*Listener, __drv_allocatesMem(Mem)) _Pre_defensive_ HQUIC* Listener ); // // Closes an existing listener. // typedef _IRQL_requires_max_(PASSIVE_LEVEL) void (QUIC_API * QUIC_LISTENER_CLOSE_FN)( _In_ _Pre_defensive_ __drv_freesMem(Mem) HQUIC Listener ); // // Starts the listener processing incoming connections. // typedef _IRQL_requires_max_(PASSIVE_LEVEL) QUIC_STATUS (QUIC_API * QUIC_LISTENER_START_FN)( _In_ _Pre_defensive_ HQUIC Listener, _In_reads_(AlpnBufferCount) _Pre_defensive_ const QUIC_BUFFER* const AlpnBuffers, _In_range_(>, 0) uint32_t AlpnBufferCount, _In_opt_ const QUIC_ADDR* LocalAddress ); // // Asynchronously stops the listener from processing incoming connections. // typedef _IRQL_requires_max_(PASSIVE_LEVEL) void (QUIC_API * QUIC_LISTENER_STOP_FN)( _In_ _Pre_defensive_ HQUIC Listener ); // // Connections // typedef enum QUIC_CONNECTION_EVENT_TYPE { QUIC_CONNECTION_EVENT_CONNECTED = 0, QUIC_CONNECTION_EVENT_SHUTDOWN_INITIATED_BY_TRANSPORT = 1, // The transport started the shutdown process. QUIC_CONNECTION_EVENT_SHUTDOWN_INITIATED_BY_PEER = 2, // The peer application started the shutdown process. QUIC_CONNECTION_EVENT_SHUTDOWN_COMPLETE = 3, // Ready for the handle to be closed. QUIC_CONNECTION_EVENT_LOCAL_ADDRESS_CHANGED = 4, QUIC_CONNECTION_EVENT_PEER_ADDRESS_CHANGED = 5, QUIC_CONNECTION_EVENT_PEER_STREAM_STARTED = 6, QUIC_CONNECTION_EVENT_STREAMS_AVAILABLE = 7, QUIC_CONNECTION_EVENT_PEER_NEEDS_STREAMS = 8, QUIC_CONNECTION_EVENT_IDEAL_PROCESSOR_CHANGED = 9, QUIC_CONNECTION_EVENT_DATAGRAM_STATE_CHANGED = 10, QUIC_CONNECTION_EVENT_DATAGRAM_RECEIVED = 11, QUIC_CONNECTION_EVENT_DATAGRAM_SEND_STATE_CHANGED = 12, QUIC_CONNECTION_EVENT_RESUMED = 13, // Server-only; provides resumption data, if any. QUIC_CONNECTION_EVENT_RESUMPTION_TICKET_RECEIVED = 14, // Client-only; provides ticket to persist, if any. QUIC_CONNECTION_EVENT_PEER_CERTIFICATE_RECEIVED = 15, // Only with QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED set } QUIC_CONNECTION_EVENT_TYPE; typedef struct QUIC_CONNECTION_EVENT { QUIC_CONNECTION_EVENT_TYPE Type; union { struct { BOOLEAN SessionResumed; _Field_range_(>, 0) uint8_t NegotiatedAlpnLength; _Field_size_(NegotiatedAlpnLength) const uint8_t* NegotiatedAlpn; } CONNECTED; struct { QUIC_STATUS Status; QUIC_UINT62 ErrorCode; // Wire format error code. } SHUTDOWN_INITIATED_BY_TRANSPORT; struct { QUIC_UINT62 ErrorCode; } SHUTDOWN_INITIATED_BY_PEER; struct { BOOLEAN HandshakeCompleted : 1; BOOLEAN PeerAcknowledgedShutdown : 1; BOOLEAN AppCloseInProgress : 1; } SHUTDOWN_COMPLETE; struct { const QUIC_ADDR* Address; } LOCAL_ADDRESS_CHANGED; struct { const QUIC_ADDR* Address; } PEER_ADDRESS_CHANGED; struct { HQUIC Stream; QUIC_STREAM_OPEN_FLAGS Flags; } PEER_STREAM_STARTED; struct { uint16_t BidirectionalCount; uint16_t UnidirectionalCount; } STREAMS_AVAILABLE; struct { BOOLEAN Bidirectional; } PEER_NEEDS_STREAMS; struct { uint16_t IdealProcessor; } IDEAL_PROCESSOR_CHANGED; struct { BOOLEAN SendEnabled; uint16_t MaxSendLength; } DATAGRAM_STATE_CHANGED; struct { const QUIC_BUFFER* Buffer; QUIC_RECEIVE_FLAGS Flags; } DATAGRAM_RECEIVED; struct { /* inout */ void* ClientContext; QUIC_DATAGRAM_SEND_STATE State; } DATAGRAM_SEND_STATE_CHANGED; struct { uint16_t ResumptionStateLength; const uint8_t* ResumptionState; } RESUMED; struct { _Field_range_(>, 0) uint32_t ResumptionTicketLength; _Field_size_(ResumptionTicketLength) const uint8_t* ResumptionTicket; } RESUMPTION_TICKET_RECEIVED; struct { QUIC_CERTIFICATE* Certificate; // Peer certificate (platform specific). Valid only during QUIC_CONNECTION_EVENT_PEER_CERTIFICATE_RECEIVED callback. uint32_t DeferredErrorFlags; // Bit flag of errors (only valid with QUIC_CREDENTIAL_FLAG_DEFER_CERTIFICATE_VALIDATION) - Schannel only, zero otherwise. QUIC_STATUS DeferredStatus; // Most severe error status (only valid with QUIC_CREDENTIAL_FLAG_DEFER_CERTIFICATE_VALIDATION) QUIC_CERTIFICATE_CHAIN* Chain; // Peer certificate chain (platform specific). Valid only during QUIC_CONNECTION_EVENT_PEER_CERTIFICATE_RECEIVED callback. } PEER_CERTIFICATE_RECEIVED; }; } QUIC_CONNECTION_EVENT; typedef _IRQL_requires_max_(PASSIVE_LEVEL) _Function_class_(QUIC_CONNECTION_CALLBACK) QUIC_STATUS (QUIC_API QUIC_CONNECTION_CALLBACK)( _In_ HQUIC Connection, _In_opt_ void* Context, _Inout_ QUIC_CONNECTION_EVENT* Event ); typedef QUIC_CONNECTION_CALLBACK *QUIC_CONNECTION_CALLBACK_HANDLER; // // Opens a new connection. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) QUIC_STATUS (QUIC_API * QUIC_CONNECTION_OPEN_FN)( _In_ _Pre_defensive_ HQUIC Registration, _In_ _Pre_defensive_ QUIC_CONNECTION_CALLBACK_HANDLER Handler, _In_opt_ void* Context, _Outptr_ _At_(*Connection, __drv_allocatesMem(Mem)) _Pre_defensive_ HQUIC* Connection ); // // Closes an existing connection. // typedef _IRQL_requires_max_(PASSIVE_LEVEL) void (QUIC_API * QUIC_CONNECTION_CLOSE_FN)( _In_ _Pre_defensive_ __drv_freesMem(Mem) HQUIC Connection ); // // Starts the shutdown process on the connection. This immediately and silently // shuts down any open streams; which will trigger callbacks for // QUIC_CONNECTION_EVENT_STREAM_CLOSED events. Does nothing if already shutdown. // Can be passed either a connection or stream handle. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) void (QUIC_API * QUIC_CONNECTION_SHUTDOWN_FN)( _In_ _Pre_defensive_ HQUIC Connection, _In_ QUIC_CONNECTION_SHUTDOWN_FLAGS Flags, _In_ _Pre_defensive_ QUIC_UINT62 ErrorCode // Application defined error code ); // // Uses the QUIC (client) handle to start a connection attempt to the // remote server. Can be passed either a connection or stream handle. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) QUIC_STATUS (QUIC_API * QUIC_CONNECTION_START_FN)( _In_ _Pre_defensive_ HQUIC Connection, _In_ _Pre_defensive_ HQUIC Configuration, _In_ QUIC_ADDRESS_FAMILY Family, _In_reads_or_z_opt_(QUIC_MAX_SNI_LENGTH) const char* ServerName, _In_ uint16_t ServerPort // Host byte order ); // // Sets the (server-side) configuration handle for the connection. This must be // called on an accepted connection in order to proceed with the QUIC handshake. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) QUIC_STATUS (QUIC_API * QUIC_CONNECTION_SET_CONFIGURATION_FN)( _In_ _Pre_defensive_ HQUIC Connection, _In_ _Pre_defensive_ HQUIC Configuration ); // // Uses the QUIC (server) handle to send a resumption ticket to the remote // client, optionally with app-specific data useful during resumption. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) QUIC_STATUS (QUIC_API * QUIC_CONNECTION_SEND_RESUMPTION_FN)( _In_ _Pre_defensive_ HQUIC Connection, _In_ QUIC_SEND_RESUMPTION_FLAGS Flags, _In_ uint16_t DataLength, _In_reads_bytes_opt_(DataLength) const uint8_t* ResumptionData ); // // Uses the QUIC (server) handle to complete resumption ticket validation. // This must be called after server app handles ticket validation and then // return QUIC_STATUS_PENDING. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) QUIC_STATUS (QUIC_API * QUIC_CONNECTION_COMP_RESUMPTION_FN)( _In_ _Pre_defensive_ HQUIC Connection, _In_ BOOLEAN Result ); // // Uses the QUIC (client) handle to complete certificate validation. // This must be called after client app handles certificate validation // and then return QUIC_STATUS_PENDING. The TlsAlert value is ignored if Result // equals TRUE (recommend just pass QUIC_TLS_ALERT_CODE_SUCCESS). // typedef _IRQL_requires_max_(DISPATCH_LEVEL) QUIC_STATUS (QUIC_API * QUIC_CONNECTION_COMP_CERT_FN)( _In_ _Pre_defensive_ HQUIC Connection, _In_ BOOLEAN Result, _In_ QUIC_TLS_ALERT_CODES TlsAlert ); // // Streams // typedef enum QUIC_STREAM_EVENT_TYPE { QUIC_STREAM_EVENT_START_COMPLETE = 0, QUIC_STREAM_EVENT_RECEIVE = 1, QUIC_STREAM_EVENT_SEND_COMPLETE = 2, QUIC_STREAM_EVENT_PEER_SEND_SHUTDOWN = 3, QUIC_STREAM_EVENT_PEER_SEND_ABORTED = 4, QUIC_STREAM_EVENT_PEER_RECEIVE_ABORTED = 5, QUIC_STREAM_EVENT_SEND_SHUTDOWN_COMPLETE = 6, QUIC_STREAM_EVENT_SHUTDOWN_COMPLETE = 7, QUIC_STREAM_EVENT_IDEAL_SEND_BUFFER_SIZE = 8, QUIC_STREAM_EVENT_PEER_ACCEPTED = 9, } QUIC_STREAM_EVENT_TYPE; typedef struct QUIC_STREAM_EVENT { QUIC_STREAM_EVENT_TYPE Type; union { struct { QUIC_STATUS Status; QUIC_UINT62 ID; BOOLEAN PeerAccepted : 1; BOOLEAN RESERVED : 7; } START_COMPLETE; struct { /* in */ uint64_t AbsoluteOffset; /* inout */ uint64_t TotalBufferLength; _Field_size_(BufferCount) /* in */ const QUIC_BUFFER* Buffers; _Field_range_(0, UINT32_MAX) /* in */ uint32_t BufferCount; /* in */ QUIC_RECEIVE_FLAGS Flags; } RECEIVE; struct { BOOLEAN Canceled; void* ClientContext; } SEND_COMPLETE; struct { QUIC_UINT62 ErrorCode; } PEER_SEND_ABORTED; struct { QUIC_UINT62 ErrorCode; } PEER_RECEIVE_ABORTED; struct { BOOLEAN Graceful; } SEND_SHUTDOWN_COMPLETE; struct { BOOLEAN ConnectionShutdown; BOOLEAN AppCloseInProgress : 1; BOOLEAN ConnectionShutdownByApp : 1; BOOLEAN ConnectionClosedRemotely : 1; BOOLEAN RESERVED : 5; QUIC_UINT62 ConnectionErrorCode; QUIC_STATUS ConnectionCloseStatus; } SHUTDOWN_COMPLETE; struct { uint64_t ByteCount; } IDEAL_SEND_BUFFER_SIZE; }; } QUIC_STREAM_EVENT; typedef _IRQL_requires_max_(PASSIVE_LEVEL) _Function_class_(QUIC_STREAM_CALLBACK) QUIC_STATUS (QUIC_API QUIC_STREAM_CALLBACK)( _In_ HQUIC Stream, _In_opt_ void* Context, _Inout_ QUIC_STREAM_EVENT* Event ); typedef QUIC_STREAM_CALLBACK *QUIC_STREAM_CALLBACK_HANDLER; // // Opens a stream on the given connection. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) QUIC_STATUS (QUIC_API * QUIC_STREAM_OPEN_FN)( _In_ _Pre_defensive_ HQUIC Connection, _In_ QUIC_STREAM_OPEN_FLAGS Flags, _In_ _Pre_defensive_ QUIC_STREAM_CALLBACK_HANDLER Handler, _In_opt_ void* Context, _Outptr_ _At_(*Stream, __drv_allocatesMem(Mem)) _Pre_defensive_ HQUIC* Stream ); // // Closes a stream handle. // typedef _IRQL_requires_max_(PASSIVE_LEVEL) void (QUIC_API * QUIC_STREAM_CLOSE_FN)( _In_ _Pre_defensive_ __drv_freesMem(Mem) HQUIC Stream ); // // Starts processing the stream. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) QUIC_STATUS (QUIC_API * QUIC_STREAM_START_FN)( _In_ _Pre_defensive_ HQUIC Stream, _In_ QUIC_STREAM_START_FLAGS Flags ); // // Shuts the stream down as specified, and waits for graceful // shutdowns to complete. Does nothing if already shut down. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) QUIC_STATUS (QUIC_API * QUIC_STREAM_SHUTDOWN_FN)( _In_ _Pre_defensive_ HQUIC Stream, _In_ QUIC_STREAM_SHUTDOWN_FLAGS Flags, _In_ _Pre_defensive_ QUIC_UINT62 ErrorCode // Application defined error code ); // // Sends data on an open stream. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) QUIC_STATUS (QUIC_API * QUIC_STREAM_SEND_FN)( _In_ _Pre_defensive_ HQUIC Stream, _In_reads_(BufferCount) _Pre_defensive_ const QUIC_BUFFER* const Buffers, _In_ uint32_t BufferCount, _In_ QUIC_SEND_FLAGS Flags, _In_opt_ void* ClientSendContext ); // // Completes a previously pended receive callback. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) void (QUIC_API * QUIC_STREAM_RECEIVE_COMPLETE_FN)( _In_ _Pre_defensive_ HQUIC Stream, _In_ uint64_t BufferLength ); // // Enables or disables stream receive callbacks. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) QUIC_STATUS (QUIC_API * QUIC_STREAM_RECEIVE_SET_ENABLED_FN)( _In_ _Pre_defensive_ HQUIC Stream, _In_ BOOLEAN IsEnabled ); // // Datagrams // // // Sends an unreliable datagram on the connection. Note, the total payload // of the send must fit in a single QUIC packet. // typedef _IRQL_requires_max_(DISPATCH_LEVEL) QUIC_STATUS (QUIC_API * QUIC_DATAGRAM_SEND_FN)( _In_ _Pre_defensive_ HQUIC Connection, _In_reads_(BufferCount) _Pre_defensive_ const QUIC_BUFFER* const Buffers, _In_ uint32_t BufferCount, _In_ QUIC_SEND_FLAGS Flags, _In_opt_ void* ClientSendContext ); // // Version 2 API Function Table. Returned from MsQuicOpenVersion when Version // is 2. Also returned from MsQuicOpen2. // typedef struct QUIC_API_TABLE { QUIC_SET_CONTEXT_FN SetContext; QUIC_GET_CONTEXT_FN GetContext; QUIC_SET_CALLBACK_HANDLER_FN SetCallbackHandler; QUIC_SET_PARAM_FN SetParam; QUIC_GET_PARAM_FN GetParam; QUIC_REGISTRATION_OPEN_FN RegistrationOpen; QUIC_REGISTRATION_CLOSE_FN RegistrationClose; QUIC_REGISTRATION_SHUTDOWN_FN RegistrationShutdown; QUIC_CONFIGURATION_OPEN_FN ConfigurationOpen; QUIC_CONFIGURATION_CLOSE_FN ConfigurationClose; QUIC_CONFIGURATION_LOAD_CREDENTIAL_FN ConfigurationLoadCredential; QUIC_LISTENER_OPEN_FN ListenerOpen; QUIC_LISTENER_CLOSE_FN ListenerClose; QUIC_LISTENER_START_FN ListenerStart; QUIC_LISTENER_STOP_FN ListenerStop; QUIC_CONNECTION_OPEN_FN ConnectionOpen; QUIC_CONNECTION_CLOSE_FN ConnectionClose; QUIC_CONNECTION_SHUTDOWN_FN ConnectionShutdown; QUIC_CONNECTION_START_FN ConnectionStart; QUIC_CONNECTION_SET_CONFIGURATION_FN ConnectionSetConfiguration; QUIC_CONNECTION_SEND_RESUMPTION_FN ConnectionSendResumptionTicket; QUIC_STREAM_OPEN_FN StreamOpen; QUIC_STREAM_CLOSE_FN StreamClose; QUIC_STREAM_START_FN StreamStart; QUIC_STREAM_SHUTDOWN_FN StreamShutdown; QUIC_STREAM_SEND_FN StreamSend; QUIC_STREAM_RECEIVE_COMPLETE_FN StreamReceiveComplete; QUIC_STREAM_RECEIVE_SET_ENABLED_FN StreamReceiveSetEnabled; QUIC_DATAGRAM_SEND_FN DatagramSend; QUIC_CONNECTION_COMP_RESUMPTION_FN ConnectionResumptionTicketValidationComplete; // Available from v2.2 QUIC_CONNECTION_COMP_CERT_FN ConnectionCertificateValidationComplete; // Available from v2.2 } QUIC_API_TABLE; #define QUIC_API_VERSION_1 1 // Not supported any more #define QUIC_API_VERSION_2 2 // Current latest #if defined(_KERNEL_MODE) && !defined(_WIN64) // // 32 bit kernel mode is no longer supported, so shim behavior in 32 bit kernel // mode // #define MsQuicClose(QuicApi) UNREFERENCED_PARAMETER((QuicApi)) #define MsQuicOpenVersion(Version, QuicApi) QUIC_STATUS_NOT_SUPPORTED #else // // Opens the API library and initializes it if this is the first call for the // process. It returns API function table for the rest of the API's functions. // MsQuicClose must be called when the app is done with the function table. // _IRQL_requires_max_(PASSIVE_LEVEL) _Check_return_ #if (__cplusplus >= 201703L || _MSVC_LANG >= 201703L) [[nodiscard]] #endif QUIC_STATUS QUIC_API MsQuicOpenVersion( _In_ uint32_t Version, _Out_ _Pre_defensive_ const void** QuicApi ); // // Cleans up the function table returned from MsQuicOpenVersion and releases the // reference on the API. // _IRQL_requires_max_(PASSIVE_LEVEL) void QUIC_API MsQuicClose( _In_ _Pre_defensive_ const void* QuicApi ); #endif // // Version specific helpers that wrap MsQuicOpenVersion. // #if defined(__cplusplus) _IRQL_requires_max_(PASSIVE_LEVEL) _Check_return_ #if (__cplusplus >= 201703L || _MSVC_LANG >= 201703L) [[nodiscard]] #endif #ifdef WIN32 __forceinline #else __attribute__((always_inline)) inline #endif QUIC_STATUS MsQuicOpen2( _Out_ _Pre_defensive_ const QUIC_API_TABLE** QuicApi ) { return MsQuicOpenVersion(QUIC_API_VERSION_2, (const void**)QuicApi); } #else #define MsQuicOpen2(QuicApi) MsQuicOpenVersion(2, (const void**)QuicApi) #endif // defined(__cplusplus) #if defined(__cplusplus) } #endif #endif // _MSQUIC_