forked from microsoft/msquic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lib.rs
1482 lines (1333 loc) · 47.6 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
use libc::c_void;
use serde::{Deserialize, Serialize};
use std::convert::TryInto;
use std::option::Option;
use std::ptr;
//
// The following starts the C interop layer of MsQuic API.
//
/// Opaque handle to a MsQuic object.
pub type Handle = *const libc::c_void;
/// Unsigned 62-bit integer.
#[allow(non_camel_case_types)]
pub type u62 = u64;
/// C-style bool.
pub type BOOLEAN = ::std::os::raw::c_uchar;
/// Family of an IP address.
pub type AddressFamily = u16;
pub const ADDRESS_FAMILY_UNSPEC: AddressFamily = 0;
pub const ADDRESS_FAMILY_INET: AddressFamily = 2;
pub const ADDRESS_FAMILY_INET6: AddressFamily = 23;
/// IPv4 address payload.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct sockaddr_in {
pub family: AddressFamily,
pub port: u16,
pub addr: u32,
pub zero: [u8; 8usize],
}
/// IPv6 address payload.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct sockaddr_in6 {
pub family: AddressFamily,
pub port: u16,
pub flow_info: u32,
pub addr: [u8; 16usize],
pub scope_id: u32,
}
/// Generic representation of IPv4 or IPv6 addresses.
#[repr(C)]
#[derive(Copy, Clone)]
pub union Addr {
pub ipv4: sockaddr_in,
pub ipv6: sockaddr_in6,
}
impl Addr {
/// Create a representation of IPv4 address and perform Network byte order conversion
/// on the port number.
pub fn ipv4(family: u16, port: u16, addr: u32) -> Addr {
Addr {
ipv4: sockaddr_in {
family,
port: port,
addr,
zero: [0, 0, 0, 0, 0, 0, 0, 0],
},
}
}
/// Create a representation of IPv6 address and perform Network byte order conversion
/// on the port number.
pub fn ipv6(
family: u16,
port: u16,
flow_info: u32,
addr: [u8; 16usize],
scope_id: u32,
) -> Addr {
Addr {
ipv6: sockaddr_in6 {
family,
port: port,
flow_info,
addr,
scope_id,
},
}
}
}
/// Helper for processing MsQuic return statuses.
pub struct Status {}
impl Status {
/// Determines if a MsQuic status is considered a succes, which includes
/// both "no error" and "pending" status codes.
#[cfg(target_os = "windows")]
pub fn succeeded(status: u32) -> bool {
(status as i32) >= 0
}
#[cfg(not(target_os = "windows"))]
pub fn succeeded(status: u32) -> bool {
(status as i32) <= 0
}
/// Determines if a MsQuic status is considered a failure.
#[cfg(target_os = "windows")]
pub fn failed(status: u32) -> bool {
(status as i32) < 0
}
#[cfg(not(target_os = "windows"))]
pub fn failed(status: u32) -> bool {
(status as i32) > 0
}
}
/// Configures how to process a registration's workload.
pub type ExecutionProfile = u32;
pub const EXECUTION_PROFILE_LOW_LATENCY: ExecutionProfile = 0;
pub const EXECUTION_PROFILE_TYPE_MAX_THROUGHPUT: ExecutionProfile = 1;
pub const EXECUTION_PROFILE_TYPE_SCAVENGER: ExecutionProfile = 2;
pub const EXECUTION_PROFILE_TYPE_REAL_TIME: ExecutionProfile = 3;
/// Represents how load balancing is performed.
pub type LoadBalancingMode = u32;
pub const LOAD_BALANCING_DISABLED: LoadBalancingMode = 0;
pub const LOAD_BALANCING_SERVER_ID_IP: LoadBalancingMode = 1;
/// Type of credentials used for a connection.
pub type CredentialType = u32;
pub const CREDENTIAL_TYPE_NONE: CredentialType = 0;
pub const CREDENTIAL_TYPE_CERTIFICATE_HASH: CredentialType = 1;
pub const CREDENTIAL_TYPE_CERTIFICATE_HASH_STORE: CredentialType = 2;
pub const CREDENTIAL_TYPE_CERTIFICATE_CONTEXT: CredentialType = 3;
pub const CREDENTIAL_TYPE_CERTIFICATE_FILE: CredentialType = 4;
pub const CREDENTIAL_TYPE_CERTIFICATE_FILE_PROTECTED: CredentialType = 5;
pub const CREDENTIAL_TYPE_CERTIFICATE_PKCS12: CredentialType = 6;
/// Modifies the default credential configuration.
pub type CredentialFlags = u32;
pub const CREDENTIAL_FLAG_NONE: CredentialFlags = 0;
pub const CREDENTIAL_FLAG_CLIENT: CredentialFlags = 1;
pub const CREDENTIAL_FLAG_LOAD_ASYNCHRONOUS: CredentialFlags = 2;
pub const CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION: CredentialFlags = 4;
pub const CREDENTIAL_FLAG_ENABLE_OCSP: CredentialFlags = 8;
pub const CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED: CredentialFlags = 16;
pub const CREDENTIAL_FLAG_DEFER_CERTIFICATE_VALIDATION: CredentialFlags = 32;
pub const CREDENTIAL_FLAG_REQUIRE_CLIENT_AUTHENTICATION: CredentialFlags = 64;
pub const CREDENTIAL_FLAG_USE_TLS_BUILTIN_CERTIFICATE_VALIDATION: CredentialFlags = 128;
pub const CREDENTIAL_FLAG_REVOCATION_CHECK_END_CERT: CredentialFlags = 256;
pub const CREDENTIAL_FLAG_REVOCATION_CHECK_CHAIN: CredentialFlags = 512;
pub const CREDENTIAL_FLAG_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT: CredentialFlags = 1024;
pub const CREDENTIAL_FLAG_IGNORE_NO_REVOCATION_CHECK: CredentialFlags = 2048;
pub const CREDENTIAL_FLAG_IGNORE_REVOCATION_OFFLINE: CredentialFlags = 4096;
pub const CREDENTIAL_FLAG_SET_ALLOWED_CIPHER_SUITES: CredentialFlags = 8192;
pub const CREDENTIAL_FLAG_USE_PORTABLE_CERTIFICATES: CredentialFlags = 16384;
/// Set of allowed TLS cipher suites.
pub type AllowedCipherSuiteFlags = u32;
pub const ALLOWED_CIPHER_SUITE_NONE: AllowedCipherSuiteFlags = 0;
pub const ALLOWED_CIPHER_SUITE_AES_128_GCM_SHA256: AllowedCipherSuiteFlags = 1;
pub const ALLOWED_CIPHER_SUITE_AES_256_GCM_SHA384: AllowedCipherSuiteFlags = 2;
pub const ALLOWED_CIPHER_SUITE_CHACHA20_POLY1305_SHA256: AllowedCipherSuiteFlags = 4;
/// Modifies the default certificate hash store configuration.
pub type CertificateHashStoreFlags = u32;
pub const CERTIFICATE_HASH_STORE_FLAG_NONE: CertificateHashStoreFlags = 0;
pub const CERTIFICATE_HASH_STORE_FLAG_MACHINE_STORE: CertificateHashStoreFlags = 1;
/// Controls connection shutdown behavior.
pub type ConnectionShutdownFlags = u32;
pub const CONNECTION_SHUTDOWN_FLAG_NONE: ConnectionShutdownFlags = 0;
pub const CONNECTION_SHUTDOWN_FLAG_SILENT: ConnectionShutdownFlags = 1;
/// Type of resumption behavior on the server side.
pub type ServerResumptionLevel = u32;
pub const SERVER_NO_RESUME: ServerResumptionLevel = 0;
pub const SERVER_RESUME_ONLY: ServerResumptionLevel = 1;
pub const SERVER_RESUME_AND_ZERORTT: ServerResumptionLevel = 2;
/// Modifies the behavior when sending resumption data.
pub type SendResumptionFlags = u32;
pub const SEND_RESUMPTION_FLAG_NONE: SendResumptionFlags = 0;
pub const SEND_RESUMPTION_FLAG_FINAL: SendResumptionFlags = 1;
/// Controls the connection's scheduling behavior for streams.
pub type StreamSchedulingScheme = u32;
pub const STREAM_SCHEDULING_SCHEME_FIFO: StreamSchedulingScheme = 0;
pub const STREAM_SCHEDULING_SCHEME_ROUND_ROBIN: StreamSchedulingScheme = 1;
pub const STREAM_SCHEDULING_SCHEME_COUNT: StreamSchedulingScheme = 2;
pub type StreamOpenFlags = u32;
pub const STREAM_OPEN_FLAG_NONE: StreamOpenFlags = 0;
pub const STREAM_OPEN_FLAG_UNIDIRECTIONAL: StreamOpenFlags = 1;
pub const STREAM_OPEN_FLAG_0_RTT: StreamOpenFlags = 2;
pub type StreamStartFlags = u32;
pub const STREAM_START_FLAG_NONE: StreamStartFlags = 0;
pub const STREAM_START_FLAG_FAIL_BLOCKED: StreamStartFlags = 1;
pub const STREAM_START_FLAG_IMMEDIATE: StreamStartFlags = 2;
pub const STREAM_START_FLAG_ASYNC: StreamStartFlags = 4;
pub const STREAM_START_FLAG_SHUTDOWN_ON_FAIL: StreamStartFlags = 8;
pub const STREAM_START_FLAG_INDICATE_PEER_ACCEPT: StreamStartFlags = 16;
/// Controls stream shutdown behavior.
pub type StreamShutdownFlags = u32;
pub const STREAM_SHUTDOWN_FLAG_NONE: StreamShutdownFlags = 0;
pub const STREAM_SHUTDOWN_FLAG_GRACEFUL: StreamShutdownFlags = 1;
pub const STREAM_SHUTDOWN_FLAG_ABORT_SEND: StreamShutdownFlags = 2;
pub const STREAM_SHUTDOWN_FLAG_ABORT_RECEIVE: StreamShutdownFlags = 4;
pub const STREAM_SHUTDOWN_FLAG_ABORT: StreamShutdownFlags = 6;
pub const STREAM_SHUTDOWN_FLAG_IMMEDIATE: StreamShutdownFlags = 8;
pub type ReceiveFlags = u32;
pub const RECEIVE_FLAG_NONE: ReceiveFlags = 0;
pub const RECEIVE_FLAG_0_RTT: ReceiveFlags = 1;
pub const RECEIVE_FLAG_FIN: ReceiveFlags = 2;
/// Controls stream and datagram send behavior.
pub type SendFlags = u32;
pub const SEND_FLAG_NONE: SendFlags = 0;
pub const SEND_FLAG_ALLOW_0_RTT: SendFlags = 1;
pub const SEND_FLAG_START: SendFlags = 2;
pub const SEND_FLAG_FIN: SendFlags = 4;
pub const SEND_FLAG_DGRAM_PRIORITY: SendFlags = 8;
pub const SEND_FLAG_DELAY_SEND: SendFlags = 16;
pub type DatagramSendState = u32;
pub const DATAGRAM_SEND_SENT: DatagramSendState = 0;
pub const DATAGRAM_SEND_LOST_SUSPECT: DatagramSendState = 1;
pub const DATAGRAM_SEND_LOST_DISCARDED: DatagramSendState = 2;
pub const DATAGRAM_SEND_ACKNOWLEDGED: DatagramSendState = 3;
pub const DATAGRAM_SEND_ACKNOWLEDGED_SPURIOUS: DatagramSendState = 4;
pub const DATAGRAM_SEND_CANCELED: DatagramSendState = 5;
/// Specifies the configuration for a new registration.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct RegistrationConfig {
pub app_name: *const i8,
pub execution_profile: ExecutionProfile,
}
/// Completion callback for a async creation of a new credential.
pub type CredentialLoadComplete =
extern "C" fn(configuration: Handle, context: *const c_void, status: u64);
/// The 20-byte hash/thumbprint of a certificate.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct CertificateHash {
pub sha_hash: [u8; 20usize],
}
/// The 20-byte hash/thumbprint and store name of a certificate.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct CertificateHashStore {
pub flags: CertificateHashStoreFlags,
pub sha_hash: [u8; 20usize],
pub store_name: [i8; 128usize],
}
/// The file paths of a certificate.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct CertificateFile {
pub private_key_file: *const i8,
pub certificate_file: *const i8,
}
/// The file paths of a protected certificate.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct CertificateFileProtected {
pub private_key_file: *const i8,
pub certificate_file: *const i8,
pub private_key_password: *const i8,
}
/// The binary blobs of a PKCS#12 certificate.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct CertificatePkcs12 {
pub ans1_blob: *const u8,
pub ans1_blob_length: u32,
pub private_key_password: *const i8,
}
/// Generic interface for a certificate.
pub type Certificate = c_void;
/// Generic interface for a certificate chain.
pub type CertificateChain = c_void;
/// Wrapper for all certificate types.
#[repr(C)]
#[derive(Copy, Clone)]
pub union CertificateUnion {
pub hash: *const CertificateHash,
pub hash_store: *const CertificateHashStore,
pub context: *const Certificate,
pub file: *const CertificateFile,
pub file_protected: *const CertificateFileProtected,
pub pkcs12: *const CertificatePkcs12,
}
/// Specifies the configuration for a new credential.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct CredentialConfig {
pub cred_type: CredentialType,
pub cred_flags: CredentialFlags,
pub certificate: CertificateUnion,
pub principle: *const i8,
pub reserved: *const c_void,
pub async_handler: Option<CredentialLoadComplete>,
pub allowed_cipher_suites: AllowedCipherSuiteFlags,
}
/// Key information for TLS session ticket encryption.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct TicketKeyConfig {
pub id: [u8; 16usize],
pub material: [u8; 64usize],
pub material_length: u8,
}
/// A generic wrapper for contiguous buffer.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Buffer {
pub length: u32,
pub buffer: *mut u8,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct NewConnectionInfo {
pub quic_version: u32,
pub local_address: *const Addr,
pub remote_address: *const Addr,
pub crypto_buffer_length: u32,
pub client_alpn_list_length: u16,
pub server_name_length: u16,
pub negotiated_alpn_length: u8,
pub crypto_buffer: *const u8,
pub client_alpn_list: *const u8,
pub negotiated_alpn: *const u8,
pub server_name: *const i8,
}
pub type TlsProtocolVersion = u32;
pub const TLS_PROTOCOL_UNKNOWN: TlsProtocolVersion = 0;
pub const TLS_PROTOCOL_1_3: TlsProtocolVersion = 12288;
pub type CipherAlgorithm = u32;
pub const CIPHER_ALGORITHM_NONE: CipherAlgorithm = 0;
pub const CIPHER_ALGORITHM_AES_128: CipherAlgorithm = 26126;
pub const CIPHER_ALGORITHM_AES_256: CipherAlgorithm = 26128;
pub const CIPHER_ALGORITHM_CHACHA20: CipherAlgorithm = 26130;
pub type HashAlgorithm = u32;
pub const HASH_ALGORITHM_NONE: HashAlgorithm = 0;
pub const HASH_ALGORITHM_SHA_256: HashAlgorithm = 32780;
pub const HASH_ALGORITHM_SHA_384: HashAlgorithm = 32781;
pub type KeyExchangeAlgorithm = u32;
pub const KEY_EXCHANGE_ALGORITHM_NONE: KeyExchangeAlgorithm = 0;
pub type CipherSuite = u32;
pub const CIPHER_SUITE_TLS_AES_128_GCM_SHA256: CipherSuite = 4865;
pub const CIPHER_SUITE_TLS_AES_256_GCM_SHA384: CipherSuite = 4866;
pub const CIPHER_SUITE_TLS_CHACHA20_POLY1305_SHA256: CipherSuite = 4867;
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
pub struct HandshakeInfo {
pub tls_protocol_version: TlsProtocolVersion,
pub cipher_algorithm: CipherAlgorithm,
pub cipher_strength: i32,
pub hash: HashAlgorithm,
pub hash_strength: i32,
pub key_exchange_algorithm: KeyExchangeAlgorithm,
pub key_exchange_strength: i32,
pub cipher_suite: CipherSuite,
}
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
pub struct QuicStatisticsTiming {
pub start: u64,
pub initial_flight_end: u64,
pub handshake_flight_end: u64,
}
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
pub struct QuicStatisticsHandshake {
pub client_flight1_bytes: u32,
pub server_flight1_bytes: u32,
pub client_flight2_bytes: u32,
}
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
pub struct QuicStatisticsSend {
pub path_mtu: u16,
pub total_packets: u64,
pub retransmittable_packets: u64,
pub suspected_lost_packets: u64,
pub spurious_lost_packets: u64,
pub total_bytes: u64,
pub total_stream_bytes: u64,
pub congestion_count: u32,
pub persistent_congestion_count: u32,
}
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
pub struct QuicStatisticsRecv {
pub total_packets: u64,
pub reordered_packets: u64,
pub dropped_packets: u64,
pub duplicate_packets: u64,
pub total_bytes: u64,
pub total_stream_bytes: u64,
pub decryption_failures: u64,
pub valid_ack_frames: u64,
}
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
pub struct QuicStatisticsMisc {
pub key_update_count: u32,
}
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
pub struct QuicStatistics {
pub correlation_id: u64,
pub _bitfield_align_1: [u8; 0],
//pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>,
pub _bitfield_1: u8,
pub rtt: u32,
pub min_rtt: u32,
pub max_rtt: u32,
pub timing: QuicStatisticsTiming,
pub handshake: QuicStatisticsHandshake,
pub send: QuicStatisticsSend,
pub recv: QuicStatisticsRecv,
pub misc: QuicStatisticsMisc,
}
/*#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct QUIC_LISTENER_STATISTICS__bindgen_ty_1__bindgen_ty_1 {
pub DroppedPackets: u64,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct QUIC_LISTENER_STATISTICS__bindgen_ty_1 {
pub Recv: QUIC_LISTENER_STATISTICS__bindgen_ty_1__bindgen_ty_1,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct QUIC_LISTENER_STATISTICS {
pub TotalAcceptedConnections: u64,
pub TotalRejectedConnections: u64,
pub Binding: QUIC_LISTENER_STATISTICS__bindgen_ty_1,
}*/
/// A helper struct for accessing performance counters.
pub struct QuicPerformance {
pub counters: [i64; PERF_COUNTER_MAX as usize],
}
pub type PerformanceCounter = u32;
pub const PERF_COUNTER_CONN_CREATED: PerformanceCounter = 0;
pub const PERF_COUNTER_CONN_HANDSHAKE_FAIL: PerformanceCounter = 1;
pub const PERF_COUNTER_CONN_APP_REJECT: PerformanceCounter = 2;
pub const PERF_COUNTER_CONN_RESUMED: PerformanceCounter = 3;
pub const PERF_COUNTER_CONN_ACTIVE: PerformanceCounter = 4;
pub const PERF_COUNTER_CONN_CONNECTED: PerformanceCounter = 5;
pub const PERF_COUNTER_CONN_PROTOCOL_ERRORS: PerformanceCounter = 6;
pub const PERF_COUNTER_CONN_NO_ALPN: PerformanceCounter = 7;
pub const PERF_COUNTER_STRM_ACTIVE: PerformanceCounter = 8;
pub const PERF_COUNTER_PKTS_SUSPECTED_LOST: PerformanceCounter = 9;
pub const PERF_COUNTER_PKTS_DROPPED: PerformanceCounter = 10;
pub const PERF_COUNTER_PKTS_DECRYPTION_FAIL: PerformanceCounter = 11;
pub const PERF_COUNTER_UDP_RECV: PerformanceCounter = 12;
pub const PERF_COUNTER_UDP_SEND: PerformanceCounter = 13;
pub const PERF_COUNTER_UDP_RECV_BYTES: PerformanceCounter = 14;
pub const PERF_COUNTER_UDP_SEND_BYTES: PerformanceCounter = 15;
pub const PERF_COUNTER_UDP_RECV_EVENTS: PerformanceCounter = 16;
pub const PERF_COUNTER_UDP_SEND_CALLS: PerformanceCounter = 17;
pub const PERF_COUNTER_APP_SEND_BYTES: PerformanceCounter = 18;
pub const PERF_COUNTER_APP_RECV_BYTES: PerformanceCounter = 19;
pub const PERF_COUNTER_CONN_QUEUE_DEPTH: PerformanceCounter = 20;
pub const PERF_COUNTER_CONN_OPER_QUEUE_DEPTH: PerformanceCounter = 21;
pub const PERF_COUNTER_CONN_OPER_QUEUED: PerformanceCounter = 22;
pub const PERF_COUNTER_CONN_OPER_COMPLETED: PerformanceCounter = 23;
pub const PERF_COUNTER_WORK_OPER_QUEUE_DEPTH: PerformanceCounter = 24;
pub const PERF_COUNTER_WORK_OPER_QUEUED: PerformanceCounter = 25;
pub const PERF_COUNTER_WORK_OPER_COMPLETED: PerformanceCounter = 26;
pub const PERF_COUNTER_MAX: PerformanceCounter = 27;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Settings {
pub is_set_flags: u64,
pub max_bytes_per_key: u64,
pub handshake_idle_timeout_ms: u64,
pub idle_timeout_ms: u64,
pub tls_client_max_send_buffer: u32,
pub tls_server_max_send_buffer: u32,
pub stream_recv_window_default: u32,
pub stream_recv_buffer_default: u32,
pub conn_flow_control_window: u32,
pub max_worker_queue_delay_us: u32,
pub max_stateless_operations: u32,
pub initial_window_packets: u32,
pub send_idle_timeout_ms: u32,
pub initiall_rtt_ms: u32,
pub max_ack_delay_ms: u32,
pub disconnect_timeout_ms: u32,
pub keep_alive_interval_ms: u32,
pub peer_bidi_stream_count: u16,
pub peer_unidi_stream_count: u16,
pub retry_memory_limit: u16,
pub load_balancing_mode: u16,
pub other_flags: u8,
pub desired_version_list: *const u32,
pub desired_version_list_length: u32,
pub minimum_mtu: u16,
pub maximum_mtu: u16,
pub mtu_discovery_search_complete_timeout_us: u64,
pub mtu_discovery_missing_probe_count: u8,
pub max_binding_stateless_operations: u16,
pub stateless_operation_expiration_ms: u16,
}
pub type ParameterLevel = u32;
pub const PARAM_LEVEL_GLOBAL: ParameterLevel = 0;
pub const PARAM_LEVEL_REGISTRATION: ParameterLevel = 1;
pub const PARAM_LEVEL_CONFIGURATION: ParameterLevel = 2;
pub const PARAM_LEVEL_LISTENER: ParameterLevel = 3;
pub const PARAM_LEVEL_CONNECTION: ParameterLevel = 4;
pub const PARAM_LEVEL_TLS: ParameterLevel = 5;
pub const PARAM_LEVEL_STREAM: ParameterLevel = 6;
pub const PARAM_GLOBAL_RETRY_MEMORY_PERCENT: u32 = 67108864;
pub const PARAM_GLOBAL_SUPPORTED_VERSIONS: u32 = 67108865;
pub const PARAM_GLOBAL_LOAD_BALACING_MODE: u32 = 67108866;
pub const PARAM_GLOBAL_PERF_COUNTERS: u32 = 67108867;
pub const PARAM_GLOBAL_SETTINGS: u32 = 67108868;
pub const PARAM_GLOBAL_VERSION: u32 = 67108869;
pub const PARAM_REGISTRATION_CID_PREFIX: u32 = 134217728;
pub const PARAM_CONFIGURATION_SETTINGS: u32 = 201326592;
pub const PARAM_CONFIGURATION_TICKET_KEYS: u32 = 201326593;
pub const PARAM_LISTENER_LOCAL_ADDRESS: u32 = 268435456;
pub const PARAM_LISTENER_STATS: u32 = 268435457;
pub const PARAM_CONN_QUIC_VERSION: u32 = 335544320;
pub const PARAM_CONN_LOCAL_ADDRESS: u32 = 335544321;
pub const PARAM_CONN_REMOTE_ADDRESS: u32 = 335544322;
pub const PARAM_CONN_IDEAL_PROCESSOR: u32 = 335544323;
pub const PARAM_CONN_SETTINGS: u32 = 335544324;
pub const PARAM_CONN_STATISTICS: u32 = 335544325;
pub const PARAM_CONN_STATISTICS_PLAT: u32 = 335544326;
pub const PARAM_CONN_SHARE_UDP_BINDING: u32 = 335544327;
pub const PARAM_CONN_LOCAL_BIDI_STREAM_COUNT: u32 = 335544328;
pub const PARAM_CONN_LOCAL_UNIDI_STREAM_COUNT: u32 = 335544329;
pub const PARAM_CONN_MAX_STREAM_IDS: u32 = 335544330;
pub const PARAM_CONN_CLOSE_REASON_PHRASE: u32 = 335544331;
pub const PARAM_CONN_STREAM_SCHEDULING_SCHEME: u32 = 335544332;
pub const PARAM_CONN_DATAGRAM_RECEIVE_ENABLED: u32 = 335544333;
pub const PARAM_CONN_DATAGRAM_SEND_ENABLED: u32 = 335544334;
pub const PARAM_CONN_RESUMPTION_TICKET: u32 = 335544336;
pub const PARAM_CONN_PEER_CERTIFICATE_VALID: u32 = 335544337;
pub const PARAM_TLS_HANDSHAKE_INFO: u32 = 402653184;
pub const PARAM_TLS_NEGOTIATED_ALPN: u32 = 402653185;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct SchannelContextAttributeW {
pub attribute: u32,
pub buffer: *mut c_void,
}
pub const PARAM_TLS_SCHANNEL_CONTEXT_ATTRIBUTE_W: u32 = 419430400;
pub const PARAM_STREAM_ID: u32 = 469762048;
pub const PARAM_STREAM_0RTT_LENGTH: u32 = 469762049;
pub const PARAM_STREAM_IDEAL_SEND_BUFFER_SIZE: u32 = 469762050;
pub const PARAM_STREAM_PRIORITY: u32 = 469762051;
pub type ListenerEventType = u32;
pub const LISTENER_EVENT_NEW_CONNECTION: ListenerEventType = 0;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ListenerEventNewConnection {
pub info: *const NewConnectionInfo,
pub connection: Handle,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union ListenerEventPayload {
pub new_connection: ListenerEventNewConnection,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct ListenerEvent {
pub event_type: ListenerEventType,
pub payload: ListenerEventPayload,
}
pub type ListenerEventHandler =
extern "C" fn(listener: Handle, context: *mut c_void, event: &ListenerEvent) -> u32;
pub type ConnectionEventType = u32;
pub const CONNECTION_EVENT_CONNECTED: ConnectionEventType = 0;
pub const CONNECTION_EVENT_SHUTDOWN_INITIATED_BY_TRANSPORT: ConnectionEventType = 1;
pub const CONNECTION_EVENT_SHUTDOWN_INITIATED_BY_PEER: ConnectionEventType = 2;
pub const CONNECTION_EVENT_SHUTDOWN_COMPLETE: ConnectionEventType = 3;
pub const CONNECTION_EVENT_LOCAL_ADDRESS_CHANGED: ConnectionEventType = 4;
pub const CONNECTION_EVENT_PEER_ADDRESS_CHANGED: ConnectionEventType = 5;
pub const CONNECTION_EVENT_PEER_STREAM_STARTED: ConnectionEventType = 6;
pub const CONNECTION_EVENT_STREAMS_AVAILABLE: ConnectionEventType = 7;
pub const CONNECTION_EVENT_PEER_NEEDS_STREAMS: ConnectionEventType = 8;
pub const CONNECTION_EVENT_IDEAL_PROCESSOR_CHANGED: ConnectionEventType = 9;
pub const CONNECTION_EVENT_DATAGRAM_STATE_CHANGED: ConnectionEventType = 10;
pub const CONNECTION_EVENT_DATAGRAM_RECEIVED: ConnectionEventType = 11;
pub const CONNECTION_EVENT_DATAGRAM_SEND_STATE_CHANGED: ConnectionEventType = 12;
pub const CONNECTION_EVENT_RESUMED: ConnectionEventType = 13;
pub const CONNECTION_EVENT_RESUMPTION_TICKET_RECEIVED: ConnectionEventType = 14;
pub const CONNECTION_EVENT_PEER_CERTIFICATE_RECEIVED: ConnectionEventType = 15;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ConnectionEventConnected {
pub session_resumed: BOOLEAN,
pub negotiated_alpn_length: u8,
pub negotiated_alpn: *const u8,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ConnectionEventConnectionShutdownByTransport {
pub status: u64,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ConnectionEventConnectionShutdownByPeer {
pub error_code: u62,
}
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
pub struct ConnectionEventShutdownComplete {
pub _bitfield: BOOLEAN,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ConnectionEventPeerStreamStarted {
pub stream: Handle,
pub flags: StreamOpenFlags,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ConnectionEventResumptionTicketReceived {
pub resumption_ticket_length: u32,
pub resumption_ticket: *const u8,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union ConnectionEventPayload {
pub connected: ConnectionEventConnected,
pub shutdown_initiated_by_transport: ConnectionEventConnectionShutdownByTransport,
pub shutdown_initiated_by_peer: ConnectionEventConnectionShutdownByPeer,
pub shutdown_complete: ConnectionEventShutdownComplete,
//pub local_address_changed: ConnectionEventLocalAddressChanged,
//pub peer_address_changed: ConnectionEventPeerAddressChanged,
pub peer_stream_started: ConnectionEventPeerStreamStarted,
//pub streams_available: ConnectionEventStreamsAvailable,
//pub ideal_processor_changed: ConnectionEventIdealProcessorChanged,
//pub datagram_state_changed: ConnectionEventDatagramStateChanged,
//pub datagram_received: ConnectionEventDatagramReceived,
//pub datagram_send_state_changed: ConnectionEventDatagramSendStateChanged,
//pub resumed: ConnectionEventResumed,
pub resumption_ticket_received: ConnectionEventResumptionTicketReceived,
//pub peer_certificated_received: ConnectionEventPeerCertificateReceived,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct ConnectionEvent {
pub event_type: ConnectionEventType,
pub payload: ConnectionEventPayload,
}
pub type ConnectionEventHandler =
extern "C" fn(connection: Handle, context: *mut c_void, event: &ConnectionEvent) -> u32;
pub type StreamEventType = u32;
pub const STREAM_EVENT_START_COMPLETE: StreamEventType = 0;
pub const STREAM_EVENT_RECEIVE: StreamEventType = 1;
pub const STREAM_EVENT_SEND_COMPLETE: StreamEventType = 2;
pub const STREAM_EVENT_PEER_SEND_SHUTDOWN: StreamEventType = 3;
pub const STREAM_EVENT_PEER_SEND_ABORTED: StreamEventType = 4;
pub const STREAM_EVENT_PEER_RECEIVE_ABORTED: StreamEventType = 5;
pub const STREAM_EVENT_SEND_SHUTDOWN_COMPLETE: StreamEventType = 6;
pub const STREAM_EVENT_SHUTDOWN_COMPLETE: StreamEventType = 7;
pub const STREAM_EVENT_IDEAL_SEND_BUFFER_SIZE: StreamEventType = 8;
pub const STREAM_EVENT_PEER_ACCEPTED: StreamEventType = 9;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct StreamEventStartComplete {
pub status: u64,
pub id: u62,
pub bit_flags: u8,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct StreamEventReceive {
pub absolute_offset: u64,
pub total_buffer_length: u64,
pub buffer: *const Buffer,
pub buffer_count: u32,
pub flags: ReceiveFlags,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union StreamEventPayload {
pub start_complete: StreamEventStartComplete,
pub receive: StreamEventReceive,
//pub send_complete: StreamEventSendComplete,
//pub peer_send_aborted: StreamEventPeerSendAborted,
//pub peer_receive_aborted: StreamEventPeerReceiveAborted,
//pub send_shutdown_complete: StreamEventSendShutdownComplete,
//pub shutdown_complete: StreamEventShutdownComplete,
//pub ideal_send_buffer_size: StreamEventIdealSendBufferSize,
}
#[repr(C)]
pub struct StreamEvent {
pub event_type: StreamEventType,
pub payload: StreamEventPayload,
}
pub type StreamEventHandler =
extern "C" fn(stream: Handle, context: *mut c_void, event: &StreamEvent) -> u32;
#[repr(C)]
struct ApiTable {
set_context: extern "C" fn(handle: Handle, context: *const c_void),
get_context: extern "C" fn(handle: Handle) -> *mut c_void,
set_callback_handler:
extern "C" fn(handle: Handle, handler: *const c_void, context: *const c_void),
set_param: extern "C" fn(
handle: Handle,
level: ParameterLevel,
param: u32,
buffer_length: u32,
buffer: *const c_void,
) -> u32,
get_param: extern "C" fn(
handle: Handle,
level: ParameterLevel,
param: u32,
buffer_length: *mut u32,
buffer: *const c_void,
) -> u32,
registration_open:
extern "C" fn(config: *const RegistrationConfig, registration: &Handle) -> u32,
registration_close: extern "C" fn(registration: Handle),
registration_shutdown: extern "C" fn(registration: Handle),
configuration_open: extern "C" fn(
registration: Handle,
alpn_buffers: *const Buffer,
alpn_buffer_cout: u32,
settings: *const Settings,
settings_size: u32,
context: *const c_void,
configuration: &*const c_void,
) -> u32,
configuration_close: extern "C" fn(configuration: Handle),
configuration_load_credential:
extern "C" fn(configuration: Handle, cred_config: *const CredentialConfig) -> u32,
listener_open: extern "C" fn(
registration: Handle,
handler: ListenerEventHandler,
context: *const c_void,
listener: &Handle,
) -> u32,
listener_close: extern "C" fn(listener: Handle),
listener_start: extern "C" fn(
listener: Handle,
alpn_buffers: *const Buffer,
alpn_buffer_cout: u32,
local_address: *const Addr,
) -> u32,
listener_stop: extern "C" fn(listener: Handle),
connection_open: extern "C" fn(
registration: Handle,
handler: ConnectionEventHandler,
context: *const c_void,
connection: &Handle,
) -> u32,
connection_close: extern "C" fn(connection: Handle),
connection_shutdown:
extern "C" fn(connection: Handle, flags: ConnectionShutdownFlags, error_code: u62),
connection_start: extern "C" fn(
connection: Handle,
configuration: Handle,
family: AddressFamily,
server_name: *const i8,
server_port: u16,
) -> u32,
connection_set_configuration: extern "C" fn(connection: Handle, configuration: Handle) -> u32,
connection_send_resumption_ticket: extern "C" fn(
connection: Handle,
flags: SendResumptionFlags,
data_length: u16,
resumption_data: *const u8,
) -> u32,
stream_open: extern "C" fn(
connection: Handle,
flags: StreamOpenFlags,
handler: StreamEventHandler,
context: *const c_void,
stream: &Handle,
) -> u32,
stream_close: extern "C" fn(stream: Handle),
stream_start: extern "C" fn(stream: Handle, flags: StreamStartFlags) -> u32,
stream_shutdown:
extern "C" fn(stream: Handle, flags: StreamShutdownFlags, error_code: u62) -> u32,
stream_send: extern "C" fn(
stream: Handle,
buffers: *const Buffer,
buffer_count: u32,
flags: SendFlags,
client_send_context: *const c_void,
) -> u32,
stream_receive_complete: extern "C" fn(stream: Handle, buffer_length: u64) -> u32,
stream_receive_set_enabled: extern "C" fn(stream: Handle, is_enabled: BOOLEAN) -> u32,
datagram_send: extern "C" fn(
connection: Handle,
buffers: *const Buffer,
buffer_count: u32,
flags: SendFlags,
client_send_context: *const c_void,
) -> u32,
}
#[link(name = "msquic")]
extern "C" {
fn MsQuicOpenVersion(version: u32, api: &*const ApiTable) -> u32;
fn MsQuicClose(api: *const ApiTable);
}
//
// The following starts the "nice" Rust API wrapper on the C interop layer.
//
/// Top level entry point for the MsQuic API.
///
/// Developper must ensure a struct containing MsQuic members such as `Connection`
/// or `Stream` declares `API` last so that the API is dropped last when the containing
/// sruct goes out of scope.
pub struct Api {
table: *const ApiTable,
}
/// The execution context for processing connections on the application's behalf.
pub struct Registration {
table: *const ApiTable,
handle: Handle,
}
/// Specifies how to configure a connection.
pub struct Configuration {
table: *const ApiTable,
handle: Handle,
}
/// A single QUIC connection.
pub struct Connection {
table: *const ApiTable,
handle: Handle,
}
/// A single server listener
pub struct Listener {
table: *const ApiTable,
handle: Handle,
}
/// A single QUIC stream on a parent connection.
pub struct Stream {
table: *const ApiTable,
handle: Handle,
}
impl From<&str> for Buffer {
fn from(data: &str) -> Buffer {
Buffer {
length: data.len() as u32,
buffer: data.as_ptr() as *mut u8,
}
}
}
impl From<&Vec<u8>> for Buffer {
fn from(data: &Vec<u8>) -> Buffer {
Buffer {
length: data.len() as u32,
buffer: data.as_ptr() as *mut u8,
}
}
}
impl From<&[u8]> for Buffer {
fn from(data: &[u8]) -> Buffer {
let buffer = Buffer {
length: data.len() as u32,
buffer: data.as_ptr() as *mut u8,
};
buffer
}
}
impl From<Buffer> for Vec<u8> {
fn from(data: Buffer) -> Vec<u8> {
let mut vec = vec![0; data.length.try_into().unwrap()];
for index in 0..data.length - 1 {
vec[index as usize] = unsafe { *data.buffer.offset(index as isize) };
}
vec
}
}
impl QuicPerformance {
pub fn counter(&self, counter: PerformanceCounter) -> i64 {
self.counters[counter as usize]
}
}
impl Settings {
pub fn new() -> Settings {
Settings {
is_set_flags: 0,
max_bytes_per_key: 0,
handshake_idle_timeout_ms: 0,
idle_timeout_ms: 0,
tls_client_max_send_buffer: 0,
tls_server_max_send_buffer: 0,
stream_recv_window_default: 0,
stream_recv_buffer_default: 0,
conn_flow_control_window: 0,
max_worker_queue_delay_us: 0,
max_stateless_operations: 0,
initial_window_packets: 0,
send_idle_timeout_ms: 0,
initiall_rtt_ms: 0,
max_ack_delay_ms: 0,
disconnect_timeout_ms: 0,
keep_alive_interval_ms: 0,
peer_bidi_stream_count: 0,
peer_unidi_stream_count: 0,
retry_memory_limit: 0,
load_balancing_mode: 0,
other_flags: 0,
desired_version_list: ptr::null(),
desired_version_list_length: 0,
minimum_mtu: 0,
maximum_mtu: 0,
mtu_discovery_search_complete_timeout_us: 0,
mtu_discovery_missing_probe_count: 0,
max_binding_stateless_operations: 0,
stateless_operation_expiration_ms: 0,