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 ;
10
6
11
7
#if TARGET_WINDOWS
12
8
using Microsoft . Win32 ;
13
9
#endif
14
10
11
+ using static System . Net . Quic . Implementations . MsQuic . Internal . MsQuicNativeMethods ;
12
+
15
13
namespace System . Net . Quic . Implementations . MsQuic . Internal
16
14
{
17
15
internal sealed unsafe class MsQuicApi
18
16
{
19
- private static readonly byte [ ] s_appName = Encoding . ASCII . GetBytes ( "System.Net.Quic" ) ;
20
-
21
17
private static readonly Version MinWindowsVersion = new Version ( 10 , 0 , 20145 , 1000 ) ;
22
18
23
- private static readonly Version MsQuicVersion = new Version ( 2 , 0 ) ;
24
-
25
19
public SafeMsQuicRegistrationHandle Registration { get ; }
26
20
27
- public QUIC_API_TABLE * ApiTable { get ; }
28
-
29
21
// This is workaround for a bug in ILTrimmer.
30
22
// Without these DynamicDependency attributes, .ctor() will be removed from the safe handles.
31
23
// Remove once fixed: https://github.com/mono/linker/issues/1660
@@ -34,28 +26,89 @@ internal sealed unsafe class MsQuicApi
34
26
[ DynamicDependency ( DynamicallyAccessedMemberTypes . PublicConstructors , typeof ( SafeMsQuicListenerHandle ) ) ]
35
27
[ DynamicDependency ( DynamicallyAccessedMemberTypes . PublicConstructors , typeof ( SafeMsQuicConnectionHandle ) ) ]
36
28
[ DynamicDependency ( DynamicallyAccessedMemberTypes . PublicConstructors , typeof ( SafeMsQuicStreamHandle ) ) ]
37
- private MsQuicApi ( QUIC_API_TABLE * apiTable )
29
+ private MsQuicApi ( NativeApi * vtable )
38
30
{
39
- ApiTable = apiTable ;
40
-
41
- fixed ( byte * pAppName = s_appName )
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
42
95
{
43
- var cfg = new QUIC_REGISTRATION_CONFIG {
44
- AppName = ( sbyte * ) pAppName ,
45
- ExecutionProfile = QUIC_EXECUTION_PROFILE . LOW_LATENCY
46
- } ;
96
+ AppName = ".NET" ,
97
+ ExecutionProfile = QUIC_EXECUTION_PROFILE . QUIC_EXECUTION_PROFILE_LOW_LATENCY
98
+ } ;
47
99
48
- QUIC_HANDLE * handle ;
49
- ThrowIfFailure ( ApiTable -> RegistrationOpen ( & cfg , & handle ) , "RegistrationOpen failed" ) ;
100
+ status = RegistrationOpenDelegate ( ref cfg , out SafeMsQuicRegistrationHandle handle ) ;
101
+ QuicExceptionHelpers . ThrowIfFailed ( status , "RegistrationOpen failed. " ) ;
50
102
51
- Registration = new SafeMsQuicRegistrationHandle ( handle ) ;
52
- }
103
+ Registration = handle ;
53
104
}
54
105
55
106
internal static MsQuicApi Api { get ; } = null ! ;
56
107
57
108
internal static bool IsQuicSupported { get ; }
58
109
110
+ private const int MsQuicVersion = 2 ;
111
+
59
112
internal static bool Tls13MayBeDisabled { get ; }
60
113
61
114
static MsQuicApi ( )
@@ -76,36 +129,21 @@ static MsQuicApi()
76
129
}
77
130
78
131
IntPtr msQuicHandle ;
79
- if ( NativeLibrary . TryLoad ( $ "{ Interop . Libraries . MsQuic } .{ MsQuicVersion . Major } ", typeof ( MsQuicApi ) . Assembly , DllImportSearchPath . AssemblyDirectory , out msQuicHandle ) ||
132
+ if ( NativeLibrary . TryLoad ( $ "{ Interop . Libraries . MsQuic } .{ MsQuicVersion } ", typeof ( MsQuicApi ) . Assembly , DllImportSearchPath . AssemblyDirectory , out msQuicHandle ) ||
80
133
NativeLibrary . TryLoad ( Interop . Libraries . MsQuic , typeof ( MsQuicApi ) . Assembly , DllImportSearchPath . AssemblyDirectory , out msQuicHandle ) )
81
134
{
82
135
try
83
136
{
84
137
if ( NativeLibrary . TryGetExport ( msQuicHandle , "MsQuicOpenVersion" , out IntPtr msQuicOpenVersionAddress ) )
85
138
{
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 ) ) )
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 ) )
89
144
{
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
- }
145
+ IsQuicSupported = true ;
146
+ Api = new MsQuicApi ( vtable ) ;
109
147
}
110
148
}
111
149
}
@@ -144,5 +182,38 @@ private static bool IsTls13Disabled()
144
182
#endif
145
183
return false ;
146
184
}
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 ; }
147
218
}
148
219
}
0 commit comments