3
3
4
4
using System . Diagnostics . CodeAnalysis ;
5
5
using System . Runtime . InteropServices ;
6
+ using System . Text ;
7
+ using Microsoft . Quic ;
8
+
9
+ using static Microsoft . Quic . MsQuic ;
6
10
7
11
#if TARGET_WINDOWS
8
12
using Microsoft . Win32 ;
9
13
#endif
10
14
11
- using static System . Net . Quic . Implementations . MsQuic . Internal . MsQuicNativeMethods ;
12
-
13
15
namespace System . Net . Quic . Implementations . MsQuic . Internal
14
16
{
15
17
internal sealed unsafe class MsQuicApi
16
18
{
19
+ private static readonly byte [ ] s_appName = Encoding . ASCII . GetBytes ( "System.Net.Quic" ) ;
20
+
17
21
private static readonly Version MinWindowsVersion = new Version ( 10 , 0 , 20145 , 1000 ) ;
18
22
23
+ private static readonly Version MsQuicVersion = new Version ( 2 , 0 ) ;
24
+
19
25
public SafeMsQuicRegistrationHandle Registration { get ; }
20
26
27
+ public QUIC_API_TABLE * ApiTable { get ; }
28
+
21
29
// This is workaround for a bug in ILTrimmer.
22
30
// Without these DynamicDependency attributes, .ctor() will be removed from the safe handles.
23
31
// Remove once fixed: https://github.com/mono/linker/issues/1660
@@ -26,89 +34,28 @@ internal sealed unsafe class MsQuicApi
26
34
[ DynamicDependency ( DynamicallyAccessedMemberTypes . PublicConstructors , typeof ( SafeMsQuicListenerHandle ) ) ]
27
35
[ DynamicDependency ( DynamicallyAccessedMemberTypes . PublicConstructors , typeof ( SafeMsQuicConnectionHandle ) ) ]
28
36
[ DynamicDependency ( DynamicallyAccessedMemberTypes . PublicConstructors , typeof ( SafeMsQuicStreamHandle ) ) ]
29
- private MsQuicApi ( NativeApi * vtable )
37
+ private MsQuicApi ( QUIC_API_TABLE * apiTable )
30
38
{
31
- uint status ;
32
-
33
- SetParamDelegate =
34
- new SetParamDelegate ( new DelegateHelper ( vtable ->SetParam ) . SetParam ) ;
35
-
36
- GetParamDelegate =
37
- new GetParamDelegate ( new DelegateHelper ( vtable ->GetParam ) . GetParam ) ;
38
-
39
- SetCallbackHandlerDelegate =
40
- new SetCallbackHandlerDelegate ( new DelegateHelper ( vtable ->SetCallbackHandler ) . SetCallbackHandler ) ;
41
-
42
- RegistrationOpenDelegate =
43
- new RegistrationOpenDelegate ( new DelegateHelper ( vtable ->RegistrationOpen ) . RegistrationOpen ) ;
44
- RegistrationCloseDelegate =
45
- Marshal . GetDelegateForFunctionPointer < RegistrationCloseDelegate > (
46
- vtable ->RegistrationClose ) ;
47
-
48
- ConfigurationOpenDelegate =
49
- new ConfigurationOpenDelegate ( new DelegateHelper ( vtable ->ConfigurationOpen ) . ConfigurationOpen ) ;
50
- ConfigurationCloseDelegate =
51
- Marshal . GetDelegateForFunctionPointer < ConfigurationCloseDelegate > (
52
- vtable ->ConfigurationClose ) ;
53
- ConfigurationLoadCredentialDelegate =
54
- new ConfigurationLoadCredentialDelegate ( new DelegateHelper ( vtable ->ConfigurationLoadCredential ) . ConfigurationLoadCredential ) ;
55
-
56
- ListenerOpenDelegate =
57
- new ListenerOpenDelegate ( new DelegateHelper ( vtable ->ListenerOpen ) . ListenerOpen ) ;
58
- ListenerCloseDelegate =
59
- Marshal . GetDelegateForFunctionPointer < ListenerCloseDelegate > (
60
- vtable ->ListenerClose ) ;
61
- ListenerStartDelegate =
62
- new ListenerStartDelegate ( new DelegateHelper ( vtable ->ListenerStart ) . ListenerStart ) ;
63
- ListenerStopDelegate =
64
- new ListenerStopDelegate ( new DelegateHelper ( vtable ->ListenerStop ) . ListenerStop ) ;
65
-
66
- ConnectionOpenDelegate =
67
- new ConnectionOpenDelegate ( new DelegateHelper ( vtable ->ConnectionOpen ) . ConnectionOpen ) ;
68
- ConnectionCloseDelegate =
69
- Marshal . GetDelegateForFunctionPointer < ConnectionCloseDelegate > (
70
- vtable ->ConnectionClose ) ;
71
- ConnectionSetConfigurationDelegate =
72
- new ConnectionSetConfigurationDelegate ( new DelegateHelper ( vtable ->ConnectionSetConfiguration ) . ConnectionSetConfiguration ) ;
73
- ConnectionShutdownDelegate =
74
- new ConnectionShutdownDelegate ( new DelegateHelper ( vtable ->ConnectionShutdown ) . ConnectionShutdown ) ;
75
- ConnectionStartDelegate =
76
- new ConnectionStartDelegate ( new DelegateHelper ( vtable ->ConnectionStart ) . ConnectionStart ) ;
77
-
78
- StreamOpenDelegate =
79
- new StreamOpenDelegate ( new DelegateHelper ( vtable ->StreamOpen ) . StreamOpen ) ;
80
- StreamCloseDelegate =
81
- Marshal . GetDelegateForFunctionPointer < StreamCloseDelegate > (
82
- vtable ->StreamClose ) ;
83
- StreamStartDelegate =
84
- new StreamStartDelegate ( new DelegateHelper ( vtable ->StreamStart ) . StreamStart ) ;
85
- StreamShutdownDelegate =
86
- new StreamShutdownDelegate ( new DelegateHelper ( vtable ->StreamShutdown ) . StreamShutdown ) ;
87
- StreamSendDelegate =
88
- new StreamSendDelegate ( new DelegateHelper ( vtable ->StreamSend ) . StreamSend ) ;
89
- StreamReceiveCompleteDelegate =
90
- new StreamReceiveCompleteDelegate ( new DelegateHelper ( vtable ->StreamReceiveComplete ) . StreamReceiveComplete ) ;
91
- StreamReceiveSetEnabledDelegate =
92
- new StreamReceiveSetEnabledDelegate ( new DelegateHelper ( vtable ->StreamReceiveSetEnabled ) . StreamReceiveSetEnabled ) ;
93
-
94
- var cfg = new RegistrationConfig
39
+ ApiTable = apiTable ;
40
+
41
+ fixed ( byte * pAppName = s_appName )
95
42
{
96
- AppName = ".NET" ,
97
- ExecutionProfile = QUIC_EXECUTION_PROFILE . QUIC_EXECUTION_PROFILE_LOW_LATENCY
98
- } ;
43
+ var cfg = new QUIC_REGISTRATION_CONFIG {
44
+ AppName = ( sbyte * ) pAppName ,
45
+ ExecutionProfile = QUIC_EXECUTION_PROFILE . LOW_LATENCY
46
+ } ;
99
47
100
- status = RegistrationOpenDelegate ( ref cfg , out SafeMsQuicRegistrationHandle handle ) ;
101
- QuicExceptionHelpers . ThrowIfFailed ( status , "RegistrationOpen failed. " ) ;
48
+ QUIC_HANDLE * handle ;
49
+ ThrowIfFailure ( ApiTable -> RegistrationOpen ( & cfg , & handle ) , "RegistrationOpen failed" ) ;
102
50
103
- Registration = handle ;
51
+ Registration = new SafeMsQuicRegistrationHandle ( handle ) ;
52
+ }
104
53
}
105
54
106
55
internal static MsQuicApi Api { get ; } = null ! ;
107
56
108
57
internal static bool IsQuicSupported { get ; }
109
58
110
- private const int MsQuicVersion = 2 ;
111
-
112
59
internal static bool Tls13MayBeDisabled { get ; }
113
60
114
61
static MsQuicApi ( )
@@ -129,21 +76,36 @@ static MsQuicApi()
129
76
}
130
77
131
78
IntPtr msQuicHandle ;
132
- if ( NativeLibrary . TryLoad ( $ "{ Interop . Libraries . MsQuic } .{ MsQuicVersion } ", typeof ( MsQuicApi ) . Assembly , DllImportSearchPath . AssemblyDirectory , out msQuicHandle ) ||
79
+ if ( NativeLibrary . TryLoad ( $ "{ Interop . Libraries . MsQuic } .{ MsQuicVersion . Major } ", typeof ( MsQuicApi ) . Assembly , DllImportSearchPath . AssemblyDirectory , out msQuicHandle ) ||
133
80
NativeLibrary . TryLoad ( Interop . Libraries . MsQuic , typeof ( MsQuicApi ) . Assembly , DllImportSearchPath . AssemblyDirectory , out msQuicHandle ) )
134
81
{
135
82
try
136
83
{
137
84
if ( NativeLibrary . TryGetExport ( msQuicHandle , "MsQuicOpenVersion" , out IntPtr msQuicOpenVersionAddress ) )
138
85
{
139
- NativeApi * vtable ;
140
- delegate * unmanaged[ Cdecl] < uint , NativeApi * * , uint > msQuicOpenVersion =
141
- ( delegate * unmanaged[ Cdecl] < uint , NativeApi * * , uint > ) msQuicOpenVersionAddress ;
142
- uint status = msQuicOpenVersion ( MsQuicVersion , & vtable ) ;
143
- if ( MsQuicStatusHelper . SuccessfulStatusCode ( status ) )
86
+ QUIC_API_TABLE * apiTable ;
87
+ delegate * unmanaged[ Cdecl] < uint , QUIC_API_TABLE * * , int > msQuicOpenVersion = ( delegate * unmanaged[ Cdecl] < uint , QUIC_API_TABLE * * , int > ) msQuicOpenVersionAddress ;
88
+ if ( StatusSucceeded ( msQuicOpenVersion ( ( uint ) MsQuicVersion . Major , & apiTable ) ) )
144
89
{
145
- IsQuicSupported = true ;
146
- Api = new MsQuicApi ( vtable ) ;
90
+ int arraySize = 4 ;
91
+ uint * libVersion = stackalloc uint [ arraySize ] ;
92
+ uint size = ( uint ) arraySize * sizeof ( uint ) ;
93
+ if ( StatusSucceeded ( apiTable ->GetParam ( null , QUIC_PARAM_GLOBAL_LIBRARY_VERSION , & size , libVersion ) ) )
94
+ {
95
+ var version = new Version ( ( int ) libVersion [ 0 ] , ( int ) libVersion [ 1 ] , ( int ) libVersion [ 2 ] , ( int ) libVersion [ 3 ] ) ;
96
+ if ( version >= MsQuicVersion )
97
+ {
98
+ Api = new MsQuicApi ( apiTable ) ;
99
+ IsQuicSupported = true ;
100
+ }
101
+ else
102
+ {
103
+ if ( NetEventSource . Log . IsEnabled ( ) )
104
+ {
105
+ NetEventSource . Info ( null , $ "Incompatible MsQuic library version '{ version } ', expecting '{ MsQuicVersion } '") ;
106
+ }
107
+ }
108
+ }
147
109
}
148
110
}
149
111
}
@@ -182,38 +144,5 @@ private static bool IsTls13Disabled()
182
144
#endif
183
145
return false ;
184
146
}
185
-
186
- // TODO: Consider updating all of these delegates to instead use function pointers.
187
- internal RegistrationOpenDelegate RegistrationOpenDelegate { get ; }
188
- internal RegistrationCloseDelegate RegistrationCloseDelegate { get ; }
189
-
190
- internal ConfigurationOpenDelegate ConfigurationOpenDelegate { get ; }
191
- internal ConfigurationCloseDelegate ConfigurationCloseDelegate { get ; }
192
- internal ConfigurationLoadCredentialDelegate ConfigurationLoadCredentialDelegate { get ; }
193
-
194
- internal ListenerOpenDelegate ListenerOpenDelegate { get ; }
195
- internal ListenerCloseDelegate ListenerCloseDelegate { get ; }
196
- internal ListenerStartDelegate ListenerStartDelegate { get ; }
197
- internal ListenerStopDelegate ListenerStopDelegate { get ; }
198
-
199
- // TODO: missing SendResumptionTicket
200
- internal ConnectionOpenDelegate ConnectionOpenDelegate { get ; }
201
- internal ConnectionCloseDelegate ConnectionCloseDelegate { get ; }
202
- internal ConnectionShutdownDelegate ConnectionShutdownDelegate { get ; }
203
- internal ConnectionStartDelegate ConnectionStartDelegate { get ; }
204
- internal ConnectionSetConfigurationDelegate ConnectionSetConfigurationDelegate { get ; }
205
-
206
- internal StreamOpenDelegate StreamOpenDelegate { get ; }
207
- internal StreamCloseDelegate StreamCloseDelegate { get ; }
208
- internal StreamStartDelegate StreamStartDelegate { get ; }
209
- internal StreamShutdownDelegate StreamShutdownDelegate { get ; }
210
- internal StreamSendDelegate StreamSendDelegate { get ; }
211
- internal StreamReceiveCompleteDelegate StreamReceiveCompleteDelegate { get ; }
212
- internal StreamReceiveSetEnabledDelegate StreamReceiveSetEnabledDelegate { get ; }
213
-
214
- internal SetCallbackHandlerDelegate SetCallbackHandlerDelegate { get ; }
215
-
216
- internal SetParamDelegate SetParamDelegate { get ; }
217
- internal GetParamDelegate GetParamDelegate { get ; }
218
147
}
219
148
}
0 commit comments