private static unsafe int NativeCallback(QUIC_HANDLE *handle, void *context, QUIC_CONNECTION_EVENT *evnt) { Console.WriteLine(evnt->Type); if (evnt->Type == QUIC_CONNECTION_EVENT_TYPE.CONNECTED) { QUIC_API_TABLE *ApiTable = (QUIC_API_TABLE *)context; void * buf = stackalloc byte[128]; uint len = 128; if (MsQuic.StatusSucceeded(ApiTable->GetParam(handle, MsQuic.QUIC_PARAM_CONN_REMOTE_ADDRESS, &len, buf))) { QuicAddr *addr = (QuicAddr *)(buf); Console.WriteLine($"Connected Family: {addr->Family}"); } } if (evnt->Type == QUIC_CONNECTION_EVENT_TYPE.PEER_STREAM_STARTED) { Console.WriteLine("Aborting Stream"); return(MsQuic.QUIC_STATUS_ABORTED); } if (evnt->Type == QUIC_CONNECTION_EVENT_TYPE.SHUTDOWN_INITIATED_BY_TRANSPORT) { Console.WriteLine($"{evnt->SHUTDOWN_INITIATED_BY_TRANSPORT.Status.ToString("X8")}: {MsQuicException.GetErrorCodeForStatus(evnt->SHUTDOWN_INITIATED_BY_TRANSPORT.Status)}"); } return(MsQuic.QUIC_STATUS_SUCCESS); }
private MsQuicApi(QUIC_API_TABLE *apiTable) { ApiTable = apiTable; fixed(byte *pAppName = s_appName) { var cfg = new QUIC_REGISTRATION_CONFIG { AppName = (sbyte *)pAppName, ExecutionProfile = QUIC_EXECUTION_PROFILE.LOW_LATENCY }; QUIC_HANDLE *handle; ThrowIfFailure(ApiTable->RegistrationOpen(&cfg, &handle), "RegistrationOpen failed"); Registration = new SafeMsQuicRegistrationHandle(handle); } }
private MsQuicApi(QUIC_API_TABLE *apiTable) { ApiTable = apiTable; fixed(byte *pAppName = "System.Net.Quic" u8) { var cfg = new QUIC_REGISTRATION_CONFIG { AppName = (sbyte *)pAppName, ExecutionProfile = QUIC_EXECUTION_PROFILE.LOW_LATENCY }; QUIC_HANDLE *handle; ThrowHelper.ThrowIfMsQuicError(ApiTable->RegistrationOpen(&cfg, &handle), "RegistrationOpen failed"); Registration = new MsQuicSafeHandle(handle, apiTable->RegistrationClose, SafeHandleType.Registration); } }
public static unsafe void Close(QUIC_API_TABLE *ApiTable) { MsQuicClose(ApiTable); }
static MsQuicApi() { IntPtr msQuicHandle; if (!NativeLibrary.TryLoad($"{Interop.Libraries.MsQuic}.{MsQuicVersion.Major}", typeof(MsQuicApi).Assembly, DllImportSearchPath.AssemblyDirectory, out msQuicHandle) && !NativeLibrary.TryLoad(Interop.Libraries.MsQuic, typeof(MsQuicApi).Assembly, DllImportSearchPath.AssemblyDirectory, out msQuicHandle)) { return; } try { if (!NativeLibrary.TryGetExport(msQuicHandle, "MsQuicOpenVersion", out IntPtr msQuicOpenVersionAddress)) { return; } QUIC_API_TABLE *apiTable = null; delegate * unmanaged[Cdecl] < uint, QUIC_API_TABLE **, int > msQuicOpenVersion = (delegate * unmanaged[Cdecl] < uint, QUIC_API_TABLE **, int >)msQuicOpenVersionAddress; if (StatusFailed(msQuicOpenVersion((uint)MsQuicVersion.Major, &apiTable))) { return; } try { int arraySize = 4; uint *libVersion = stackalloc uint[arraySize]; uint size = (uint)arraySize * sizeof(uint); if (StatusFailed(apiTable->GetParam(null, QUIC_PARAM_GLOBAL_LIBRARY_VERSION, &size, libVersion))) { return; } var version = new Version((int)libVersion[0], (int)libVersion[1], (int)libVersion[2], (int)libVersion[3]); if (version < MsQuicVersion) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(null, $"Incompatible MsQuic library version '{version}', expecting '{MsQuicVersion}'"); } return; } // Assume SChannel is being used on windows and query for the actual provider from the library QUIC_TLS_PROVIDER provider = OperatingSystem.IsWindows() ? QUIC_TLS_PROVIDER.SCHANNEL : QUIC_TLS_PROVIDER.OPENSSL; size = sizeof(QUIC_TLS_PROVIDER); apiTable->GetParam(null, QUIC_PARAM_GLOBAL_TLS_PROVIDER, &size, &provider); UsesSChannelBackend = provider == QUIC_TLS_PROVIDER.SCHANNEL; if (UsesSChannelBackend) { // Implies windows platform, check TLS1.3 availability if (!IsWindowsVersionSupported()) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(null, $"Current Windows version ({Environment.OSVersion}) is not supported by QUIC. Minimal supported version is {MinWindowsVersion}"); } return; } Tls13ServerMayBeDisabled = IsTls13Disabled(isServer: true); Tls13ClientMayBeDisabled = IsTls13Disabled(isServer: false); } Api = new MsQuicApi(apiTable); IsQuicSupported = true; } finally { if (!IsQuicSupported && NativeLibrary.TryGetExport(msQuicHandle, "MsQuicClose", out IntPtr msQuicClose)) { // Gracefully close the API table ((delegate * unmanaged[Cdecl] < QUIC_API_TABLE *, void >)msQuicClose)(apiTable); } } } finally { if (!IsQuicSupported) { NativeLibrary.Free(msQuicHandle); } } }