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); }
#pragma warning restore CS3016 private static unsafe int NativeCallback(QUIC_HANDLE *connection, void *context, QUIC_CONNECTION_EVENT *connectionEvent) { GCHandle gcHandle = GCHandle.FromIntPtr((IntPtr)context); Debug.Assert(gcHandle.IsAllocated); Debug.Assert(gcHandle.Target is not null); var state = (State)gcHandle.Target; if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(state, $"{state.Handle} Connection received event {connectionEvent->Type}"); } try { switch (connectionEvent->Type) { case QUIC_CONNECTION_EVENT_TYPE.CONNECTED: return(HandleEventConnected(state, ref *connectionEvent)); case QUIC_CONNECTION_EVENT_TYPE.SHUTDOWN_INITIATED_BY_TRANSPORT: return(HandleEventShutdownInitiatedByTransport(state, ref *connectionEvent)); case QUIC_CONNECTION_EVENT_TYPE.SHUTDOWN_INITIATED_BY_PEER: return(HandleEventShutdownInitiatedByPeer(state, ref *connectionEvent)); case QUIC_CONNECTION_EVENT_TYPE.SHUTDOWN_COMPLETE: return(HandleEventShutdownComplete(state, ref *connectionEvent)); case QUIC_CONNECTION_EVENT_TYPE.PEER_STREAM_STARTED: return(HandleEventNewStream(state, ref *connectionEvent)); case QUIC_CONNECTION_EVENT_TYPE.STREAMS_AVAILABLE: return(HandleEventStreamsAvailable(state, ref *connectionEvent)); case QUIC_CONNECTION_EVENT_TYPE.PEER_CERTIFICATE_RECEIVED: return(HandleEventPeerCertificateReceived(state, ref *connectionEvent)); default: return(QUIC_STATUS_SUCCESS); } } catch (Exception ex) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Error(state, $"{state.Handle} Exception occurred during handling {connectionEvent->Type} connection callback: {ex}"); } if (state.ConnectTcs != null) { // This is opportunistic if we get exception and have ability to propagate it to caller. state.ConnectTcs.TrySetException(ex); state.Connection = null; state.ConnectTcs = null; } else { Debug.Fail($"{state.Handle} Exception occurred during handling {connectionEvent->Type} connection callback: {ex}"); } // TODO: trigger an exception on any outstanding async calls. return(QUIC_STATUS_INTERNAL_ERROR); } }