Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
MsQuicConnection.cs
Go to the documentation of this file.
12
14
16{
17 internal sealed class State
18 {
20
21 public string TraceId;
22
24
26
28
30
31 public readonly TaskCompletionSource<uint> ShutdownTcs = new TaskCompletionSource<uint>(TaskCreationOptions.RunContinuationsAsynchronously);
32
34
36
37 public bool Connected;
38
39 public long AbortErrorCode = -1L;
40
41 public int StreamCount;
42
43 private bool _closing;
44
46
48
50
51 public RemoteCertificateValidationCallback RemoteCertificateValidationCallback;
52
53 public bool IsServer;
54
55 public string TargetHost;
56
58 {
59 SingleWriter = true
60 });
61
63 {
64 bool flag;
65 lock (this)
66 {
68 flag = _closing && StreamCount == 0;
69 }
70 if (flag)
71 {
72 if (System.Net.NetEventSource.Log.IsEnabled())
73 {
74 System.Net.NetEventSource.Info(this, $"{TraceId} releasing handle after last stream.", "RemoveStream");
75 }
76 Handle?.Dispose();
77 }
78 }
79
81 {
82 MsQuicStream msQuicStream = new MsQuicStream(this, streamHandle, flags);
83 if (AcceptQueue.Writer.TryWrite(msQuicStream))
84 {
85 return true;
86 }
87 msQuicStream.Dispose();
88 return false;
89 }
90
92 {
93 lock (this)
94 {
95 if (_closing)
96 {
97 return false;
98 }
100 return true;
101 }
102 }
103
104 public void SetClosing()
105 {
106 lock (this)
107 {
108 _closing = true;
109 }
110 }
111 }
112
113 private static readonly Oid s_clientAuthOid = new Oid("1.3.6.1.5.5.7.3.2", "1.3.6.1.5.5.7.3.2");
114
115 private static readonly Oid s_serverAuthOid = new Oid("1.3.6.1.5.5.7.3.1", "1.3.6.1.5.5.7.3.1");
116
117 private static readonly MsQuicNativeMethods.ConnectionCallbackDelegate s_connectionDelegate = NativeCallbackHandler;
118
120
121 private readonly State _state = new State();
122
123 private int _disposed;
124
126
127 private readonly EndPoint _remoteEndPoint;
128
130
132
134
136
138
139 internal override bool Connected => _state.Connected;
140
141 internal string TraceId()
142 {
143 return _state.TraceId;
144 }
145
146 public MsQuicConnection(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, MsQuicListener.State listenerState, SafeMsQuicConnectionHandle handle, bool remoteCertificateRequired = false, X509RevocationMode revocationMode = X509RevocationMode.Offline, RemoteCertificateValidationCallback remoteCertificateValidationCallback = null, ServerCertificateSelectionCallback serverCertificateSelectionCallback = null)
147 {
148 _state.Handle = handle;
149 _state.StateGCHandle = GCHandle.Alloc(_state);
150 _state.RemoteCertificateRequired = remoteCertificateRequired;
151 _state.RevocationMode = revocationMode;
152 _state.RemoteCertificateValidationCallback = remoteCertificateValidationCallback;
153 _state.IsServer = true;
154 _localEndPoint = localEndPoint;
155 _remoteEndPoint = remoteEndPoint;
156 try
157 {
159 }
160 catch
161 {
163 throw;
164 }
165 _state.ListenerState = listenerState;
166 _state.TraceId = MsQuicTraceHelper.GetTraceId(_state.Handle);
167 if (System.Net.NetEventSource.Log.IsEnabled())
168 {
169 System.Net.NetEventSource.Info(_state, $"{TraceId()} Inbound connection created", ".ctor");
170 }
171 }
172
174 {
175 if (options.RemoteEndPoint == null)
176 {
177 throw new ArgumentNullException("RemoteEndPoint");
178 }
179 _remoteEndPoint = options.RemoteEndPoint;
181 _state.RemoteCertificateRequired = true;
182 if (options.ClientAuthenticationOptions != null)
183 {
184 _state.RevocationMode = options.ClientAuthenticationOptions.CertificateRevocationCheckMode;
185 _state.RemoteCertificateValidationCallback = options.ClientAuthenticationOptions.RemoteCertificateValidationCallback;
186 _state.TargetHost = options.ClientAuthenticationOptions.TargetHost;
187 }
188 _state.StateGCHandle = GCHandle.Alloc(_state);
189 try
190 {
191 uint status = MsQuicApi.Api.ConnectionOpenDelegate(MsQuicApi.Api.Registration, s_connectionDelegate, GCHandle.ToIntPtr(_state.StateGCHandle), out _state.Handle);
192 QuicExceptionHelpers.ThrowIfFailed(status, "Could not open the connection.");
193 }
194 catch
195 {
197 throw;
198 }
199 _state.TraceId = MsQuicTraceHelper.GetTraceId(_state.Handle);
200 if (System.Net.NetEventSource.Log.IsEnabled())
201 {
202 System.Net.NetEventSource.Info(_state, $"{TraceId()} Outbound connection created", ".ctor");
203 }
204 }
205
206 private static uint HandleEventConnected(State state, ref MsQuicNativeMethods.ConnectionEvent connectionEvent)
207 {
208 if (state.Connected)
209 {
210 return 0u;
211 }
212 if (state.IsServer)
213 {
214 state.Connected = true;
215 MsQuicListener.State listenerState = state.ListenerState;
216 state.ListenerState = null;
217 if (listenerState != null && listenerState.PendingConnections.TryRemove(state.Handle.DangerousGetHandle(), out var value))
218 {
219 if (listenerState.AcceptConnectionQueue.Writer.TryWrite(value))
220 {
221 return 0u;
222 }
223 value.Dispose();
224 }
225 return 2151743490u;
226 }
228 state.Connection._localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);
229 state.Connection.SetNegotiatedAlpn(connectionEvent.Data.Connected.NegotiatedAlpn, connectionEvent.Data.Connected.NegotiatedAlpnLength);
230 state.Connection = null;
231 state.Connected = true;
232 state.ConnectTcs.SetResult(0u);
233 state.ConnectTcs = null;
234 return 0u;
235 }
236
238 {
239 if (!state.Connected && state.ConnectTcs != null)
240 {
241 state.Connection = null;
242 uint status = connectionEvent.Data.ShutdownInitiatedByTransport.Status;
243 Exception currentStackTrace = QuicExceptionHelpers.CreateExceptionForHResult(status, "Connection has been shutdown by transport.");
244 state.ConnectTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(currentStackTrace));
245 state.ConnectTcs = null;
246 }
247 state.AbortErrorCode = 0L;
248 state.AcceptQueue.Writer.TryComplete();
249 return 0u;
250 }
251
253 {
254 state.AbortErrorCode = connectionEvent.Data.ShutdownInitiatedByPeer.ErrorCode;
255 state.AcceptQueue.Writer.TryComplete();
256 return 0u;
257 }
258
260 {
261 state.StateGCHandle.Free();
262 if (state.ListenerState != null)
263 {
264 if (state.ListenerState.PendingConnections.TryRemove(state.Handle.DangerousGetHandle(), out var value))
265 {
266 value.Dispose();
267 }
268 state.ListenerState = null;
269 }
270 state.Connection = null;
271 state.ShutdownTcs.SetResult(0u);
272 state.AcceptQueue.Writer.TryComplete();
273 TaskCompletionSource taskCompletionSource = null;
274 TaskCompletionSource taskCompletionSource2 = null;
275 lock (state)
276 {
277 taskCompletionSource = state.NewUnidirectionalStreamsAvailable;
278 taskCompletionSource2 = state.NewBidirectionalStreamsAvailable;
279 state.NewUnidirectionalStreamsAvailable = null;
280 state.NewBidirectionalStreamsAvailable = null;
281 }
284 return 0u;
285 }
286
287 private static uint HandleEventNewStream(State state, ref MsQuicNativeMethods.ConnectionEvent connectionEvent)
288 {
289 SafeMsQuicStreamHandle safeMsQuicStreamHandle = new SafeMsQuicStreamHandle(connectionEvent.Data.PeerStreamStarted.Stream);
290 if (!state.TryQueueNewStream(safeMsQuicStreamHandle, connectionEvent.Data.PeerStreamStarted.Flags))
291 {
292 safeMsQuicStreamHandle.Dispose();
293 }
294 return 0u;
295 }
296
298 {
299 TaskCompletionSource taskCompletionSource = null;
300 TaskCompletionSource taskCompletionSource2 = null;
301 lock (state)
302 {
303 if (connectionEvent.Data.StreamsAvailable.UniDirectionalCount > 0)
304 {
305 taskCompletionSource = state.NewUnidirectionalStreamsAvailable;
306 state.NewUnidirectionalStreamsAvailable = null;
307 }
308 if (connectionEvent.Data.StreamsAvailable.BiDirectionalCount > 0)
309 {
310 taskCompletionSource2 = state.NewBidirectionalStreamsAvailable;
311 state.NewBidirectionalStreamsAvailable = null;
312 }
313 }
314 taskCompletionSource?.SetResult();
315 taskCompletionSource2?.SetResult();
316 return 0u;
317 }
318
320 {
321 SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None;
322 X509Chain x509Chain = null;
323 X509Certificate2 x509Certificate = null;
324 X509Certificate2Collection x509Certificate2Collection = null;
325 try
326 {
327 if (connectionEvent.Data.PeerCertificateReceived.PlatformCertificateHandle != IntPtr.Zero)
328 {
330 {
331 x509Certificate = new X509Certificate2(connectionEvent.Data.PeerCertificateReceived.PlatformCertificateHandle);
332 }
333 else
334 {
335 ReadOnlySpan<MsQuicNativeMethods.QuicBuffer> readOnlySpan = new ReadOnlySpan<MsQuicNativeMethods.QuicBuffer>((void*)connectionEvent.Data.PeerCertificateReceived.PlatformCertificateHandle, sizeof(MsQuicNativeMethods.QuicBuffer));
336 x509Certificate = new X509Certificate2(new ReadOnlySpan<byte>(readOnlySpan[0].Buffer, (int)readOnlySpan[0].Length));
337 if (connectionEvent.Data.PeerCertificateReceived.PlatformCertificateChainHandle != IntPtr.Zero)
338 {
339 readOnlySpan = new ReadOnlySpan<MsQuicNativeMethods.QuicBuffer>((void*)connectionEvent.Data.PeerCertificateReceived.PlatformCertificateChainHandle, sizeof(MsQuicNativeMethods.QuicBuffer));
340 if (readOnlySpan[0].Length != 0 && readOnlySpan[0].Buffer != null)
341 {
342 x509Certificate2Collection = new X509Certificate2Collection();
343 x509Certificate2Collection.Import(new ReadOnlySpan<byte>(readOnlySpan[0].Buffer, (int)readOnlySpan[0].Length));
344 }
345 }
346 }
347 }
348 if (x509Certificate == null)
349 {
350 if (System.Net.NetEventSource.Log.IsEnabled() && state.RemoteCertificateRequired)
351 {
352 System.Net.NetEventSource.Error(state, $"{state.TraceId} Remote certificate required, but no remote certificate received", "HandleEventPeerCertificateReceived");
353 }
354 sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable;
355 }
356 else
357 {
358 x509Chain = new X509Chain();
359 x509Chain.ChainPolicy.RevocationMode = state.RevocationMode;
360 x509Chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
362 if (x509Certificate2Collection != null && x509Certificate2Collection.Count > 1)
363 {
364 x509Chain.ChainPolicy.ExtraStore.AddRange(x509Certificate2Collection);
365 }
366 sslPolicyErrors |= System.Net.CertificateValidation.BuildChainAndVerifyProperties(x509Chain, x509Certificate, checkCertName: true, state.IsServer, state.TargetHost);
367 }
368 if (!state.RemoteCertificateRequired)
369 {
370 sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateNotAvailable;
371 }
372 state.RemoteCertificate = x509Certificate;
373 if (state.RemoteCertificateValidationCallback != null)
374 {
375 bool success = state.RemoteCertificateValidationCallback(state, x509Certificate, x509Chain, sslPolicyErrors);
376 state.RemoteCertificateValidationCallback = (object _, X509Certificate _, X509Chain _, SslPolicyErrors _) => success;
377 if (!success && System.Net.NetEventSource.Log.IsEnabled())
378 {
379 System.Net.NetEventSource.Error(state, $"{state.TraceId} Remote certificate rejected by verification callback", "HandleEventPeerCertificateReceived");
380 }
381 if (!success)
382 {
383 if (state.IsServer)
384 {
385 return 2151743490u;
386 }
388 }
389 return 0u;
390 }
391 if (System.Net.NetEventSource.Log.IsEnabled())
392 {
393 System.Net.NetEventSource.Info(state, $"{state.TraceId} Certificate validation for '${x509Certificate?.Subject}' finished with ${sslPolicyErrors}", "HandleEventPeerCertificateReceived");
394 }
395 if (sslPolicyErrors != 0)
396 {
397 if (state.IsServer)
398 {
399 return 2151743488u;
400 }
402 }
403 return 0u;
404 }
405 catch (Exception ex)
406 {
407 if (System.Net.NetEventSource.Log.IsEnabled())
408 {
409 System.Net.NetEventSource.Error(state, $"{state.TraceId} Certificate validation failed ${ex.Message}", "HandleEventPeerCertificateReceived");
410 }
411 throw;
412 }
413 }
414
416 {
418 try
419 {
420 return await _state.AcceptQueue.Reader.ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
421 }
423 {
425 }
426 }
427
429 {
430 TaskCompletionSource newUnidirectionalStreamsAvailable = _state.NewUnidirectionalStreamsAvailable;
431 if (newUnidirectionalStreamsAvailable == null)
432 {
433 int remoteAvailableUnidirectionalStreamCount = GetRemoteAvailableUnidirectionalStreamCount();
434 lock (_state)
435 {
437 {
439 {
441 }
442 if (remoteAvailableUnidirectionalStreamCount > 0)
443 {
445 }
446 _state.NewUnidirectionalStreamsAvailable = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
447 }
448 newUnidirectionalStreamsAvailable = _state.NewUnidirectionalStreamsAvailable;
449 }
450 }
451 return new ValueTask(newUnidirectionalStreamsAvailable.Task.WaitAsync(cancellationToken));
452 }
453
455 {
456 TaskCompletionSource newBidirectionalStreamsAvailable = _state.NewBidirectionalStreamsAvailable;
457 if (newBidirectionalStreamsAvailable == null)
458 {
459 int remoteAvailableBidirectionalStreamCount = GetRemoteAvailableBidirectionalStreamCount();
460 lock (_state)
461 {
463 {
465 {
467 }
468 if (remoteAvailableBidirectionalStreamCount > 0)
469 {
471 }
472 _state.NewBidirectionalStreamsAvailable = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
473 }
474 newBidirectionalStreamsAvailable = _state.NewBidirectionalStreamsAvailable;
475 }
476 }
477 return new ValueTask(newBidirectionalStreamsAvailable.Task.WaitAsync(cancellationToken));
478 }
479
481 {
483 if (!Connected)
484 {
486 }
487 return new MsQuicStream(_state, QUIC_STREAM_OPEN_FLAGS.UNIDIRECTIONAL);
488 }
489
491 {
493 if (!Connected)
494 {
496 }
498 }
499
504
509
511 {
513 if (_configuration == null)
514 {
515 throw new InvalidOperationException("ConnectAsync must not be called on a connection obtained from a listener.");
516 }
517 QUIC_ADDRESS_FAMILY family = _remoteEndPoint.AddressFamily switch
518 {
519 AddressFamily.Unspecified => QUIC_ADDRESS_FAMILY.UNSPEC,
520 AddressFamily.InterNetwork => QUIC_ADDRESS_FAMILY.INET,
521 AddressFamily.InterNetworkV6 => QUIC_ADDRESS_FAMILY.INET6,
523 };
524 _state.Connection = this;
525 string serverName;
526 int port;
528 {
530 uint status = MsQuicApi.Api.SetParamDelegate(_state.Handle, QUIC_PARAM_LEVEL.CONNECTION, 2u, (uint)sizeof(MsQuicNativeMethods.SOCKADDR_INET), (byte*)(&sOCKADDR_INET));
531 QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");
532 serverName = _state.TargetHost ?? ((IPEndPoint)_remoteEndPoint).Address.ToString();
533 port = ((IPEndPoint)_remoteEndPoint).Port;
534 }
535 else
536 {
538 {
539 throw new ArgumentException($"Unsupported remote endpoint type '{_remoteEndPoint.GetType()}'.");
540 }
541 port = ((DnsEndPoint)_remoteEndPoint).Port;
542 string host = ((DnsEndPoint)_remoteEndPoint).Host;
543 if (!string.IsNullOrEmpty(_state.TargetHost) && !host.Equals(_state.TargetHost, StringComparison.InvariantCultureIgnoreCase) && IPAddress.TryParse(host, out IPAddress address))
544 {
546 uint status = MsQuicApi.Api.SetParamDelegate(_state.Handle, QUIC_PARAM_LEVEL.CONNECTION, 2u, (uint)sizeof(MsQuicNativeMethods.SOCKADDR_INET), (byte*)(&sOCKADDR_INET2));
547 QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");
548 serverName = _state.TargetHost;
549 }
550 else
551 {
552 serverName = host;
553 }
554 }
555 TaskCompletionSource<uint> taskCompletionSource = (_state.ConnectTcs = new TaskCompletionSource<uint>(TaskCreationOptions.RunContinuationsAsynchronously));
556 try
557 {
558 uint status = MsQuicApi.Api.ConnectionStartDelegate(_state.Handle, _configuration, family, serverName, (ushort)port);
559 QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");
561 _configuration = null;
562 }
563 catch
564 {
566 _state.Connection = null;
567 throw;
568 }
569 return new ValueTask(taskCompletionSource.Task);
570 }
571
573 {
574 _state.Connection = this;
575 try
576 {
577 MsQuicApi.Api.ConnectionShutdownDelegate(_state.Handle, Flags, ErrorCode);
578 }
579 catch
580 {
581 _state.Connection = null;
582 throw;
583 }
584 return new ValueTask(_state.ShutdownTcs.Task);
585 }
586
587 internal void SetNegotiatedAlpn(IntPtr alpn, int alpnLength)
588 {
589 if (alpn != IntPtr.Zero && alpnLength != 0)
590 {
591 byte[] array = new byte[alpnLength];
592 Marshal.Copy(alpn, array, 0, alpnLength);
594 }
595 }
596
597 private static uint NativeCallbackHandler(IntPtr connection, IntPtr context, ref MsQuicNativeMethods.ConnectionEvent connectionEvent)
598 {
599 State state = (State)GCHandle.FromIntPtr(context).Target;
600 if (System.Net.NetEventSource.Log.IsEnabled())
601 {
602 System.Net.NetEventSource.Info(state, $"{state.TraceId} Connection received event {connectionEvent.Type}", "NativeCallbackHandler");
603 }
604 try
605 {
606 return connectionEvent.Type switch
607 {
608 QUIC_CONNECTION_EVENT_TYPE.CONNECTED => HandleEventConnected(state, ref connectionEvent),
609 QUIC_CONNECTION_EVENT_TYPE.SHUTDOWN_INITIATED_BY_TRANSPORT => HandleEventShutdownInitiatedByTransport(state, ref connectionEvent),
610 QUIC_CONNECTION_EVENT_TYPE.SHUTDOWN_INITIATED_BY_PEER => HandleEventShutdownInitiatedByPeer(state, ref connectionEvent),
611 QUIC_CONNECTION_EVENT_TYPE.SHUTDOWN_COMPLETE => HandleEventShutdownComplete(state, ref connectionEvent),
612 QUIC_CONNECTION_EVENT_TYPE.PEER_STREAM_STARTED => HandleEventNewStream(state, ref connectionEvent),
613 QUIC_CONNECTION_EVENT_TYPE.STREAMS_AVAILABLE => HandleEventStreamsAvailable(state, ref connectionEvent),
614 QUIC_CONNECTION_EVENT_TYPE.PEER_CERTIFICATE_RECEIVED => HandleEventPeerCertificateReceived(state, ref connectionEvent),
615 _ => 0u,
616 };
617 }
618 catch (Exception ex)
619 {
620 if (System.Net.NetEventSource.Log.IsEnabled())
621 {
622 System.Net.NetEventSource.Error(state, $"{state.TraceId} Exception occurred during handling {connectionEvent.Type} connection callback: {ex}", "NativeCallbackHandler");
623 }
624 if (state.ConnectTcs != null)
625 {
626 state.ConnectTcs.TrySetException(ex);
627 state.Connection = null;
628 state.ConnectTcs = null;
629 }
630 return 2151743491u;
631 }
632 }
633
634 public override void Dispose()
635 {
636 Dispose(disposing: true);
637 GC.SuppressFinalize(this);
638 }
639
641 {
642 Dispose(disposing: false);
643 }
644
645 private async Task FlushAcceptQueue()
646 {
647 _state.AcceptQueue.Writer.TryComplete();
648 await foreach (MsQuicStream item in _state.AcceptQueue.Reader.ReadAllAsync().ConfigureAwait(continueOnCapturedContext: false))
649 {
650 if (item.CanRead)
651 {
652 item.AbortRead(4294967295L);
653 }
654 if (item.CanWrite)
655 {
656 item.AbortWrite(4294967295L);
657 }
658 item.Dispose();
659 }
660 }
661
662 private void Dispose(bool disposing)
663 {
664 if (Interlocked.Exchange(ref _disposed, 1) != 0)
665 {
666 return;
667 }
668 if (System.Net.NetEventSource.Log.IsEnabled())
669 {
670 System.Net.NetEventSource.Info(_state, $"{TraceId()} Connection disposing {disposing}", "Dispose");
671 }
673 {
674 MsQuicApi.Api.ConnectionShutdownDelegate(_state.Handle, QUIC_CONNECTION_SHUTDOWN_FLAGS.SILENT, 0L);
675 }
676 bool flag = false;
677 lock (_state)
678 {
679 _state.Connection = null;
680 if (_state.StreamCount == 0)
681 {
682 flag = true;
683 }
684 else
685 {
687 }
688 }
689 FlushAcceptQueue().GetAwaiter().GetResult();
691 if (flag)
692 {
693 if (System.Net.NetEventSource.Log.IsEnabled())
694 {
695 System.Net.NetEventSource.Info(_state, $"{TraceId()} Connection releasing handle", "Dispose");
696 }
698 }
699 }
700
701 internal override ValueTask CloseAsync(long errorCode, CancellationToken cancellationToken = default(CancellationToken))
702 {
703 if (_disposed == 1)
704 {
705 return default(ValueTask);
706 }
707 return ShutdownAsync(QUIC_CONNECTION_SHUTDOWN_FLAGS.NONE, errorCode);
708 }
709
710 private void ThrowIfDisposed()
711 {
712 if (_disposed == 1)
713 {
714 throw new ObjectDisposedException("MsQuicStream");
715 }
716 }
717}
static void SuppressFinalize(object obj)
Definition GC.cs:202
Definition GC.cs:8
static unsafe SslPolicyErrors BuildChainAndVerifyProperties(X509Chain chain, X509Certificate2 remoteCertificate, bool checkCertName, bool isServer, string hostName)
virtual AddressFamily AddressFamily
Definition EndPoint.cs:8
static bool TryParse([NotNullWhen(true)] string? ipString, [NotNullWhen(true)] out IPAddress? address)
Definition IPAddress.cs:303
static readonly System.Net.NetEventSource Log
static void Info(object thisOrContextObject, FormattableString formattableString=null, [CallerMemberName] string memberName=null)
static void Error(object thisOrContextObject, FormattableString formattableString, [CallerMemberName] string memberName=null)
static unsafe IPEndPoint INetToIPEndPoint(ref MsQuicNativeMethods.SOCKADDR_INET inetAddress)
static unsafe MsQuicNativeMethods.SOCKADDR_INET IPEndPointToINet(IPEndPoint endpoint)
static unsafe ushort GetUShortParam(MsQuicApi api, SafeHandle nativeObject, QUIC_PARAM_LEVEL level, uint param)
static unsafe MsQuicNativeMethods.SOCKADDR_INET GetINetParam(MsQuicApi api, SafeHandle nativeObject, QUIC_PARAM_LEVEL level, uint param)
static string GetTraceId(SafeMsQuicStreamHandle handle)
static void ThrowIfFailed(uint status, string message=null, Exception innerException=null)
static Exception CreateExceptionForHResult(uint status, string message=null, Exception innerException=null)
static SafeMsQuicConfigurationHandle Create(QuicClientConnectionOptions options)
bool TryQueueNewStream(SafeMsQuicStreamHandle streamHandle, QUIC_STREAM_OPEN_FLAGS flags)
RemoteCertificateValidationCallback RemoteCertificateValidationCallback
ValueTask ShutdownAsync(QUIC_CONNECTION_SHUTDOWN_FLAGS Flags, long ErrorCode)
MsQuicConnection(QuicClientConnectionOptions options)
static uint HandleEventStreamsAvailable(State state, ref MsQuicNativeMethods.ConnectionEvent connectionEvent)
unsafe override ValueTask ConnectAsync(CancellationToken cancellationToken=default(CancellationToken))
override SslApplicationProtocol NegotiatedApplicationProtocol
override ValueTask WaitForAvailableUnidirectionalStreamsAsync(CancellationToken cancellationToken=default(CancellationToken))
override ValueTask WaitForAvailableBidirectionalStreamsAsync(CancellationToken cancellationToken=default(CancellationToken))
static uint HandleEventShutdownInitiatedByTransport(State state, ref MsQuicNativeMethods.ConnectionEvent connectionEvent)
static uint HandleEventShutdownComplete(State state, ref MsQuicNativeMethods.ConnectionEvent connectionEvent)
static unsafe uint HandleEventPeerCertificateReceived(State state, ref MsQuicNativeMethods.ConnectionEvent connectionEvent)
override async ValueTask< QuicStreamProvider > AcceptStreamAsync(CancellationToken cancellationToken=default(CancellationToken))
override ValueTask CloseAsync(long errorCode, CancellationToken cancellationToken=default(CancellationToken))
static uint HandleEventNewStream(State state, ref MsQuicNativeMethods.ConnectionEvent connectionEvent)
MsQuicConnection(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, MsQuicListener.State listenerState, SafeMsQuicConnectionHandle handle, bool remoteCertificateRequired=false, X509RevocationMode revocationMode=X509RevocationMode.Offline, RemoteCertificateValidationCallback remoteCertificateValidationCallback=null, ServerCertificateSelectionCallback serverCertificateSelectionCallback=null)
static readonly MsQuicNativeMethods.ConnectionCallbackDelegate s_connectionDelegate
static uint NativeCallbackHandler(IntPtr connection, IntPtr context, ref MsQuicNativeMethods.ConnectionEvent connectionEvent)
static uint HandleEventConnected(State state, ref MsQuicNativeMethods.ConnectionEvent connectionEvent)
static uint HandleEventShutdownInitiatedByPeer(State state, ref MsQuicNativeMethods.ConnectionEvent connectionEvent)
readonly ConcurrentDictionary< IntPtr, MsQuicConnection > PendingConnections
readonly Channel< MsQuicConnection > AcceptConnectionQueue
static Exception GetConnectionAbortedException(long errorCode)
Definition ThrowHelper.cs:5
static void Copy(int[] source, int startIndex, IntPtr destination, int length)
Definition Marshal.cs:800
static string net_quic_not_connected
Definition SR.cs:40
static string net_quic_cert_chain_validation
Definition SR.cs:38
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string net_quic_unsupported_address_family
Definition SR.cs:26
static string net_quic_cert_custom_validation
Definition SR.cs:36
Definition SR.cs:7
static int Exchange(ref int location1, int value)
new Task< TResult > WaitAsync(CancellationToken cancellationToken)
Definition Task.cs:231
new TaskAwaiter< TResult > GetAwaiter()
Definition Task.cs:221
static readonly IntPtr Zero
Definition IntPtr.cs:18
static IntPtr ToIntPtr(GCHandle value)
Definition GCHandle.cs:138
static GCHandle Alloc(object? value)
Definition GCHandle.cs:81
static GCHandle FromIntPtr(IntPtr value)
Definition GCHandle.cs:127
static ValueTask CompletedTask
Definition ValueTask.cs:71