Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
MsQuicListener.cs
Go to the documentation of this file.
10
12
14{
15 internal sealed class State
16 {
18
19 public string TraceId;
20
22
24
26
28
30
32 {
33 ConnectionOptions.IdleTimeout = options.IdleTimeout;
34 ConnectionOptions.MaxBidirectionalStreams = options.MaxBidirectionalStreams;
35 ConnectionOptions.MaxUnidirectionalStreams = options.MaxUnidirectionalStreams;
36 bool flag = false;
37 if (options.ServerAuthenticationOptions != null)
38 {
39 AuthenticationOptions.ClientCertificateRequired = options.ServerAuthenticationOptions.ClientCertificateRequired;
40 AuthenticationOptions.CertificateRevocationCheckMode = options.ServerAuthenticationOptions.CertificateRevocationCheckMode;
41 AuthenticationOptions.RemoteCertificateValidationCallback = options.ServerAuthenticationOptions.RemoteCertificateValidationCallback;
42 AuthenticationOptions.ServerCertificateSelectionCallback = options.ServerAuthenticationOptions.ServerCertificateSelectionCallback;
43 AuthenticationOptions.ApplicationProtocols = options.ServerAuthenticationOptions.ApplicationProtocols;
44 if (options.ServerAuthenticationOptions.ServerCertificate == null && options.ServerAuthenticationOptions.ServerCertificateContext == null && options.ServerAuthenticationOptions.ServerCertificateSelectionCallback != null)
45 {
46 flag = true;
47 }
48 }
49 if (!flag)
50 {
52 }
55 {
56 SingleReader = true,
57 SingleWriter = true
58 });
59 }
60 }
61
62 private static readonly MsQuicNativeMethods.ListenerCallbackDelegate s_listenerDelegate = NativeCallbackHandler;
63
64 private readonly State _state;
65
67
68 private volatile bool _disposed;
69
70 private readonly IPEndPoint _listenEndPoint;
71
73
75 {
76 if (options.ListenEndPoint == null)
77 {
78 throw new ArgumentNullException("ListenEndPoint");
79 }
80 _state = new State(options);
82 try
83 {
84 uint status = MsQuicApi.Api.ListenerOpenDelegate(MsQuicApi.Api.Registration, s_listenerDelegate, GCHandle.ToIntPtr(_stateHandle), out _state.Handle);
85 QuicExceptionHelpers.ThrowIfFailed(status, "ListenerOpen failed.");
86 }
87 catch
88 {
90 throw;
91 }
92 _state.TraceId = MsQuicTraceHelper.GetTraceId(_state.Handle);
93 if (System.Net.NetEventSource.Log.IsEnabled())
94 {
95 System.Net.NetEventSource.Info(_state, $"{_state.TraceId} Listener created", ".ctor");
96 }
98 if (System.Net.NetEventSource.Log.IsEnabled())
99 {
100 System.Net.NetEventSource.Info(_state, $"{_state.TraceId} Listener started", ".ctor");
101 }
102 }
103
105 {
107 try
108 {
109 return await _state.AcceptConnectionQueue.Reader.ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
110 }
112 {
114 }
115 }
116
117 public override void Dispose()
118 {
119 Dispose(disposing: true);
120 GC.SuppressFinalize(this);
121 }
122
124 {
125 Dispose(disposing: false);
126 }
127
128 private void Dispose(bool disposing)
129 {
130 if (!_disposed)
131 {
132 Stop();
135 {
137 }
139 _disposed = true;
140 }
141 }
142
169
170 private void Stop()
171 {
172 if (_state != null)
173 {
174 _state.AcceptConnectionQueue?.Writer.TryComplete();
175 if (_state.Handle != null)
176 {
177 MsQuicApi.Api.ListenerStopDelegate(_state.Handle);
178 }
179 }
180 }
181
182 private unsafe static uint NativeCallbackHandler(IntPtr listener, IntPtr context, ref MsQuicNativeMethods.ListenerEvent evt)
183 {
184 State state = (State)GCHandle.FromIntPtr(context).Target;
185 if (evt.Type != 0)
186 {
187 return 2151743491u;
188 }
191 try
192 {
193 ref MsQuicNativeMethods.NewConnectionInfo reference = ref *evt.Data.NewConnection.Info;
196 string targetHost = string.Empty;
197 if (reference.ServerNameLength > 0 && reference.ServerName != IntPtr.Zero)
198 {
199 targetHost = Marshal.PtrToStringAnsi(reference.ServerName, reference.ServerNameLength);
200 }
203 {
204 try
205 {
206 safeMsQuicConfigurationHandle = SafeMsQuicConfigurationHandle.Create(state.ConnectionOptions, state.AuthenticationOptions, targetHost);
207 }
208 catch (Exception ex)
209 {
210 if (System.Net.NetEventSource.Log.IsEnabled())
211 {
212 System.Net.NetEventSource.Error(state, $"[Listener#{state.GetHashCode()}] Exception occurred during creating configuration in connection callback: {ex}", "NativeCallbackHandler");
213 }
214 }
216 {
217 return 2151743491u;
218 }
219 }
220 safeMsQuicConnectionHandle = new SafeMsQuicConnectionHandle(evt.Data.NewConnection.Connection);
221 uint status = MsQuicApi.Api.ConnectionSetConfigurationDelegate(safeMsQuicConnectionHandle, safeMsQuicConfigurationHandle);
223 {
224 msQuicConnection = new MsQuicConnection(localEndPoint, remoteEndPoint, state, safeMsQuicConnectionHandle, state.AuthenticationOptions.ClientCertificateRequired, state.AuthenticationOptions.CertificateRevocationCheckMode, state.AuthenticationOptions.RemoteCertificateValidationCallback);
225 msQuicConnection.SetNegotiatedAlpn(reference.NegotiatedAlpn, reference.NegotiatedAlpnLength);
226 if (!state.PendingConnections.TryAdd(safeMsQuicConnectionHandle.DangerousGetHandle(), msQuicConnection))
227 {
228 msQuicConnection.Dispose();
229 }
230 return 0u;
231 }
232 }
233 catch (Exception ex2)
234 {
235 if (System.Net.NetEventSource.Log.IsEnabled())
236 {
237 System.Net.NetEventSource.Error(state, $"[Listener#{state.GetHashCode()}] Exception occurred during handling {evt.Type} connection callback: {ex2}", "NativeCallbackHandler");
238 }
239 }
240 safeMsQuicConnectionHandle?.SetHandleAsInvalid();
241 msQuicConnection?.Dispose();
242 return 2151743491u;
243 }
244
245 private void ThrowIfDisposed()
246 {
247 if (_disposed)
248 {
249 throw new ObjectDisposedException("MsQuicStream");
250 }
251 }
252}
static void SuppressFinalize(object obj)
Definition GC.cs:202
Definition GC.cs:8
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 void Prepare(List< SslApplicationProtocol > alpnProtocols, [NotNull] out MemoryHandle[] handles, [NotNull] out MsQuicNativeMethods.QuicBuffer[] buffers)
static void Return(ref MemoryHandle[] handles, ref MsQuicNativeMethods.QuicBuffer[] buffers)
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 SafeMsQuicConfigurationHandle Create(QuicClientConnectionOptions options)
readonly ConcurrentDictionary< IntPtr, MsQuicConnection > PendingConnections
readonly SafeMsQuicConfigurationHandle ConnectionConfiguration
readonly Channel< MsQuicConnection > AcceptConnectionQueue
static readonly MsQuicNativeMethods.ListenerCallbackDelegate s_listenerDelegate
unsafe IPEndPoint Start(QuicListenerOptions options)
override async ValueTask< QuicConnectionProvider > AcceptConnectionAsync(CancellationToken cancellationToken=default(CancellationToken))
static unsafe uint NativeCallbackHandler(IntPtr listener, IntPtr context, ref MsQuicNativeMethods.ListenerEvent evt)
static unsafe? string PtrToStringAnsi(IntPtr ptr)
Definition Marshal.cs:630
static unsafe IntPtr UnsafeAddrOfPinnedArrayElement(Array arr, int index)
Definition Marshal.cs:775
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