-
Notifications
You must be signed in to change notification settings - Fork 680
Expand file tree
/
Copy pathquic_platform.h
More file actions
764 lines (658 loc) · 22.5 KB
/
Copy pathquic_platform.h
File metadata and controls
764 lines (658 loc) · 22.5 KB
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
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
Abstract:
Platform definitions.
Supported Environments:
Windows user mode
Windows kernel mode
Linux user mode
--*/
#pragma once
#include <stddef.h>
#if defined(__cplusplus)
extern "C" {
#endif
#define IS_POWER_OF_TWO(x) (((x) != 0) && (((x) & ((x) - 1)) == 0))
#define CXPLAT_MAX(a,b) (((a) > (b)) ? (a) : (b))
#define CXPLAT_MIN(a,b) (((a) < (b)) ? (a) : (b))
//
// Time unit conversion.
//
#define NS_TO_US(x) ((x) / 1000)
#define US_TO_NS(x) ((x) * 1000)
#define NS100_TO_US(x) ((x) / 10)
#define US_TO_NS100(x) ((x) * 10)
#define MS_TO_NS100(x) ((x)*10000)
#define NS100_TO_MS(x) ((x)/10000)
#define US_TO_MS(x) ((x) / 1000)
#define MS_TO_US(x) ((x) * 1000)
#define US_TO_S(x) ((x) / (1000 * 1000))
#define S_TO_US(x) ((x) * 1000 * 1000)
#define S_TO_NS(x) ((x) * 1000 * 1000 * 1000)
#define MS_TO_S(x) ((x) / 1000)
#define S_TO_MS(x) ((x) * 1000)
#define CXPLAT_CONTAINING_RECORD(address, type, field) \
((type *)((uint8_t*)(address) - offsetof(type, field)))
#define CXPLAT_FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
#define CXPLAT_STRUCT_SIZE_THRU_FIELD(Type, Field) \
(offsetof(Type, Field) + sizeof(((Type*)0)->Field))
#define CXPLAT_STRUCT_HAS_FIELD(Type, Size, Field) \
(Size >= CXPLAT_STRUCT_SIZE_THRU_FIELD(Type, Field))
typedef struct CXPLAT_LIST_ENTRY {
struct CXPLAT_LIST_ENTRY* Flink;
struct CXPLAT_LIST_ENTRY* Blink;
} CXPLAT_LIST_ENTRY;
typedef struct CXPLAT_SLIST_ENTRY {
struct CXPLAT_SLIST_ENTRY* Next;
} CXPLAT_SLIST_ENTRY;
#ifndef FORCEINLINE
#if (_MSC_VER >= 1200)
#define FORCEINLINE __forceinline
#else
#define FORCEINLINE QUIC_INLINE
#endif
#endif
//
// Different pool tags used for marking allocations.
//
#define QUIC_POOL_GENERIC 'CIUQ' // QUIC - Generic QUIC
#define QUIC_POOL_SILO '00cQ' // Qc00 - QUIC Silo
#define QUIC_POOL_CONN '10cQ' // Qc01 - QUIC connection
#define QUIC_POOL_TP '20cQ' // Qc02 - QUIC connection transport parameters
#define QUIC_POOL_STREAM '30cQ' // Qc03 - QUIC stream
#define QUIC_POOL_SBUF '40cQ' // Qc04 - QUIC stream buffer
#define QUIC_POOL_META '50cQ' // Qc05 - QUIC sent frame metadata
#define QUIC_POOL_DATA '60cQ' // Qc06 - QUIC datagram buffer
#define QUIC_POOL_TEST '70cQ' // Qc07 - QUIC test code
#define QUIC_POOL_PERF '80cQ' // Qc08 - QUIC perf code
#define QUIC_POOL_TOOL '90cQ' // Qc09 - QUIC tool code
#define QUIC_POOL_WORKER 'A0cQ' // Qc0A - QUIC Worker
#define QUIC_POOL_LISTENER 'B0cQ' // Qc0B - QUIC Listener
#define QUIC_POOL_CID 'C0cQ' // Qc0C - QUIC CID
#define QUIC_POOL_CIDHASH 'D0cQ' // Qc0D - QUIC CID Hash
#define QUIC_POOL_CIDLIST 'E0cQ' // Qc0E - QUIC CID List Entry
#define QUIC_POOL__UNUSED_1_ 'F0cQ' // Qc0F - UNUSED
#define QUIC_POOL_ALPN '01cQ' // Qc10 - QUIC ALPN
#define QUIC_POOL_RANGE '11cQ' // Qc11 - QUIC Range
#define QUIC_POOL_SENDBUF '21cQ' // Qc12 - QUIC Send Buffer
#define QUIC_POOL_RECVBUF '31cQ' // Qc13 - QUIC Recv Buffer
#define QUIC_POOL_TIMERWHEEL '41cQ' // Qc14 - QUIC Timer Wheel
#define QUIC_POOL_REGISTRATION '51cQ' // Qc15 - QUIC Registration
#define QUIC_POOL_CONFIG '61cQ' // Qc16 - QUIC configuration
#define QUIC_POOL_BINDING '71cQ' // Qc17 - QUIC Core binding
#define QUIC_POOL_API '81cQ' // Qc18 - QUIC API Table
#define QUIC_POOL_PERPROC '91cQ' // Qc19 - QUIC Per Proc Context
#define QUIC_POOL_PLATFORM_SENDCTX 'A1cQ' // Qc1A - QUIC Platform Send Context
#define QUIC_POOL_TLS_ACHCTX 'B1cQ' // Qc1B - QUIC Platform TLS ACH Context
#define QUIC_POOL_TLS_SNI 'C1cQ' // Qc1C - QUIC Platform TLS SNI
#define QUIC_POOL_TLS_PRINCIPAL 'D1cQ' // Qc1D - QUIC Platform TLS Principal
#define QUIC_POOL_TLS_CTX 'E1cQ' // Qc1E - QUIC Platform TLS Context
#define QUIC_POOL_TLS_TRANSPARAMS 'F1cQ' // Qc1F - QUIC Platform TLS Transport Parameters
#define QUIC_POOL_CUSTOM_THREAD '02cQ' // Qc20 - QUIC Platform Customm Thread Context
#define QUIC_POOL_TLS_SECCONF '12cQ' // Qc21 - QUIC Platform TLS Sec Config
#define QUIC_POOL_TLS_PACKETKEY '22cQ' // Qc22 - QUIC Platform TLS Packet Key
#define QUIC_POOL_TLS_KEY '32cQ' // Qc23 - QUIC Platform TLS Key
#define QUIC_POOL_TLS_HP_KEY '42cQ' // Qc24 - QUIC Platform TLS HP Key
#define QUIC_POOL_TLS_HASH '52cQ' // Qc25 - QUIC Platform TLS Hash
#define QUIC_POOL_TLS_EXTRAS '62cQ' // Qc26 - QUIC Platform TLS Extra Data
#define QUIC_POOL_TMP_ALLOC '72cQ' // Qc27 - QUIC temporary alloc
#define QUIC_POOL_PLATFORM_TMP_ALLOC '82cQ' // Qc28 - QUIC Platform temporary alloc
#define QUIC_POOL_PLATFORM_PROC '92cQ' // Qc29 - QUIC Platform Processor info
#define QUIC_POOL_PLATFORM_GENERIC 'A2cQ' // Qc2A - QUIC Platform generic
#define QUIC_POOL_DATAPATH 'B2cQ' // Qc2B - QUIC Platform datapath
#define QUIC_POOL_SOCKET 'C2cQ' // Qc2C - QUIC Platform socket
#define QUIC_POOL_STORAGE 'D2cQ' // Qc2D - QUIC Platform storage
#define QUIC_POOL_HASHTABLE 'E2cQ' // Qc2E - QUIC Platform hashtable
#define QUIC_POOL_HASHTABLE_MEMBER 'F2cQ' // Qc2F - QUIC Platform hashtable member lists
#define QUIC_POOL_LOOKUP_HASHTABLE '03cQ' // Qc30 - QUIC Lookup Hash Table
#define QUIC_POOL_REMOTE_HASH '13cQ' // Qc31 - QUIC Remote Hash Entry
#define QUIC_POOL_SERVERNAME '23cQ' // Qc32 - QUIC Server Name
#define QUIC_POOL_APP_RESUMPTION_DATA '33cQ' // Qc33 - QUIC App Resumption Data
#define QUIC_POOL_INITIAL_TOKEN '43cQ' // Qc34 - QUIC Initial Token
#define QUIC_POOL_CLOSE_REASON '53cQ' // Qc35 - QUIC Close Reason
#define QUIC_POOL_SERVER_CRYPTO_TICKET '63cQ' // Qc36 - QUIC Crypto Server Ticket Buffer
#define QUIC_POOL_CLIENT_CRYPTO_TICKET '73cQ' // Qc37 - QUIC Crypto Client Ticket Buffer
#define QUIC_POOL_CRYPTO_RESUMPTION_TICKET '83cQ' // Qc38 - QUIC Crypto Resumption Ticket
#define QUIC_POOL_TLS_BUFFER '93cQ' // Qc39 - QUIC Tls Buffer
#define QUIC_POOL_SEND_REQUEST 'A3cQ' // Qc3A - QUIC Send Request
#define QUIC_POOL_API_CTX 'B3cQ' // Qc3B - QUIC API Context
#define QUIC_POOL_STATELESS_CTX 'C3cQ' // Qc3C - QUIC Stateless Context
#define QUIC_POOL_OPER 'D3cQ' // Qc3D - QUIC Operation
#define QUIC_POOL_EVENT 'E3cQ' // Qc3E - QUIC Event
#define QUIC_POOL_TLS_PFX 'F3cQ' // Qc3F - QUIC Platform PFX
#define QUIC_POOL_VERSION_SETTINGS '04cQ' // Qc40 - QUIC App-supplied version settings
#define QUIC_POOL_DEFAULT_COMPAT_VER_LIST '14cQ' // Qc41 - QUIC Default compatible versions list
#define QUIC_POOL_VERSION_INFO '24cQ' // Qc42 - QUIC Version info
#define QUIC_POOL_PROCESS '34cQ' // Qc43 - QUIC Process
#define QUIC_POOL_TLS_TMP_TP '44cQ' // Qc44 - QUIC Platform TLS Temporary TP storage
#define QUIC_POOL_PCP '54cQ' // Qc45 - QUIC PCP
#define QUIC_POOL_DATAPATH_ADDRESSES '64cQ' // Qc46 - QUIC Datapath Addresses
#define QUIC_POOL_TLS_TICKET_KEY '74cQ' // Qc47 - QUIC Platform TLS ticket key
#define QUIC_POOL_TLS_CIPHER_SUITE_STRING '84cQ' // Qc48 - QUIC TLS cipher suite string
#define QUIC_POOL_PLATFORM_WORKER '94cQ' // Qc49 - QUIC platform worker
#define QUIC_POOL_ROUTE_RESOLUTION_WORKER 'A4cQ' // Qc4A - QUIC route resolution worker
#define QUIC_POOL_ROUTE_RESOLUTION_OPER 'B4cQ' // Qc4B - QUIC route resolution operation
#define QUIC_POOL_EXECUTION_CONFIG 'C4cQ' // Qc4C - QUIC execution config
#define QUIC_POOL_APP_BUFFER_CHUNK 'D4cQ' // Qc4D - QUIC receive chunk for app buffers
#define QUIC_POOL_CONN_POOL_API_TABLE 'E4cQ' // Qc4E - QUIC Connection Pool API table
#define QUIC_POOL_DATAPATH_RSS_CONFIG 'F4cQ' // Qc4F - QUIC Datapath RSS configuration
#define QUIC_POOL_TLS_AUX_DATA '05cQ' // Qc50 - QUIC TLS Backing Aux data
#define QUIC_POOL_TLS_RECORD_ENTRY '15cQ' // Qc51 - QUIC TLS Backing Record storage
#define QUIC_POOL_XDP_MAP_CONFIG '25cQ' // Qc52 - QUIC XDP Map Config
typedef enum CXPLAT_THREAD_FLAGS {
CXPLAT_THREAD_FLAG_NONE = 0x0000,
CXPLAT_THREAD_FLAG_SET_IDEAL_PROC = 0x0001,
CXPLAT_THREAD_FLAG_SET_AFFINITIZE = 0x0002,
CXPLAT_THREAD_FLAG_HIGH_PRIORITY = 0x0004
} CXPLAT_THREAD_FLAGS;
#ifdef DEFINE_ENUM_FLAG_OPERATORS
DEFINE_ENUM_FLAG_OPERATORS(CXPLAT_THREAD_FLAGS);
#endif
#ifdef _KERNEL_MODE
#define CX_PLATFORM_TYPE 1
#include "quic_platform_winkernel.h"
#elif _WIN32
#define CX_PLATFORM_TYPE 2
#include "quic_platform_winuser.h"
#elif CX_PLATFORM_LINUX
#define CX_PLATFORM_TYPE 3
#define CX_PLATFORM_USES_TLS_BUILTIN_CERTIFICATE 1
#include "quic_platform_posix.h"
#elif CX_PLATFORM_DARWIN
#define CX_PLATFORM_TYPE 4
#include "quic_platform_posix.h"
#else
#define CX_PLATFORM_TYPE 0xFF
#error "Unsupported Platform"
#endif
#if defined(__cplusplus)
extern "C" {
#endif
//
// Small Computation Helpers
//
//
// Exponentially weighted moving average
//
QUIC_INLINE
uint64_t
CxPlatEwma(
_In_ uint64_t Average,
_In_ uint64_t Sample,
_In_ uint64_t Weight
)
{
CXPLAT_DBG_ASSERT(Weight > 0);
return ((Weight - 1) * Average + Sample) / Weight;
}
//
// Library Initialization
//
//
// Called in main, DLLMain or DriverEntry.
//
PAGEDX
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatSystemLoad(
void
);
//
// Called in main (exit), DLLMain or DriverUnload.
//
PAGEDX
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatSystemUnload(
void
);
//
// Initializes the PAL library. Calls to this and
// CxPlatformUninitialize must be serialized and cannot overlap.
//
PAGEDX
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatInitialize(
void
);
//
// Uninitializes the PAL library. Calls to this and
// CxPlatformInitialize must be serialized and cannot overlap.
//
PAGEDX
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatUninitialize(
void
);
#if defined(__cplusplus)
}
#endif
//
// List Abstraction
//
#define QuicListEntryValidate(Entry) \
CXPLAT_DBG_ASSERT( \
(((Entry->Flink)->Blink) == Entry) && \
(((Entry->Blink)->Flink) == Entry))
FORCEINLINE
void
CxPlatListInitializeHead(
_Out_ CXPLAT_LIST_ENTRY* ListHead
)
{
ListHead->Flink = ListHead->Blink = ListHead;
}
_Must_inspect_result_
FORCEINLINE
BOOLEAN
CxPlatListIsEmpty(
_In_ const CXPLAT_LIST_ENTRY* ListHead
)
{
CXPLAT_DBG_ASSERT(ListHead->Flink != NULL);
return (BOOLEAN)(ListHead->Flink == ListHead);
}
_Must_inspect_result_
FORCEINLINE
BOOLEAN
CxPlatListIsEmptyNoFence(
_In_ const CXPLAT_LIST_ENTRY* ListHead
)
{
return (BOOLEAN)(QuicReadPtrNoFence((void**)&ListHead->Flink) == ListHead);
}
FORCEINLINE
void
CxPlatListInsertHead(
_Inout_ CXPLAT_LIST_ENTRY* ListHead,
_Out_ __drv_aliasesMem CXPLAT_LIST_ENTRY* Entry
)
{
QuicListEntryValidate(ListHead);
CXPLAT_LIST_ENTRY* Flink = ListHead->Flink;
Entry->Flink = Flink;
Entry->Blink = ListHead;
Flink->Blink = Entry;
ListHead->Flink = Entry;
}
FORCEINLINE
void
CxPlatListInsertTail(
_Inout_ CXPLAT_LIST_ENTRY* ListHead,
_Inout_ __drv_aliasesMem CXPLAT_LIST_ENTRY* Entry
)
{
QuicListEntryValidate(ListHead);
CXPLAT_LIST_ENTRY* Blink = ListHead->Blink;
Entry->Flink = ListHead;
Entry->Blink = Blink;
Blink->Flink = Entry;
ListHead->Blink = Entry;
}
FORCEINLINE
void
CxPlatListInsertAfter(
_Inout_ CXPLAT_LIST_ENTRY* ListEntry,
_Inout_ __drv_aliasesMem CXPLAT_LIST_ENTRY* NewEntry
)
{
QuicListEntryValidate(ListEntry);
CXPLAT_LIST_ENTRY* Flink = ListEntry->Flink;
ListEntry->Flink = NewEntry;
NewEntry->Flink = Flink;
NewEntry->Blink = ListEntry;
Flink->Blink = NewEntry;
}
FORCEINLINE
CXPLAT_LIST_ENTRY*
CxPlatListRemoveHead(
_Inout_ CXPLAT_LIST_ENTRY* ListHead
)
{
QuicListEntryValidate(ListHead);
CXPLAT_LIST_ENTRY* Entry = ListHead->Flink; // cppcheck-suppress shadowFunction
CXPLAT_LIST_ENTRY* Flink = Entry->Flink;
ListHead->Flink = Flink;
Flink->Blink = ListHead;
return Entry;
}
FORCEINLINE
BOOLEAN
CxPlatListEntryRemove(
_In_ CXPLAT_LIST_ENTRY* Entry
)
{
QuicListEntryValidate(Entry);
CXPLAT_LIST_ENTRY* Flink = Entry->Flink;
CXPLAT_LIST_ENTRY* Blink = Entry->Blink;
Blink->Flink = Flink;
Flink->Blink = Blink;
return (BOOLEAN)(Flink == Blink);
}
QUIC_INLINE
void
CxPlatListMoveItems(
_Inout_ CXPLAT_LIST_ENTRY* Source,
_Inout_ CXPLAT_LIST_ENTRY* Destination
)
{
//
// If there are items, copy them.
//
if (!CxPlatListIsEmpty(Source)) {
if (CxPlatListIsEmpty(Destination)) {
//
// Copy the links of the Source.
//
Destination->Flink = Source->Flink;
Destination->Blink = Source->Blink;
//
// Fix the item's links to point to new head.
//
Destination->Flink->Blink = Destination;
Destination->Blink->Flink = Destination;
} else {
//
// Fix Destination's current last item to point
// to the first of Source.
//
Source->Flink->Blink = Destination->Blink;
Destination->Blink->Flink = Source->Flink;
//
// Fix Destination's new last item to be the of Source's last item.
//
Source->Blink->Flink = Destination;
Destination->Blink = Source->Blink;
}
//
// Reset the Source to empty list.
//
CxPlatListInitializeHead(Source);
}
}
FORCEINLINE
void
CxPlatListPushEntry(
_Inout_ CXPLAT_SLIST_ENTRY* ListHead,
_Inout_ __drv_aliasesMem CXPLAT_SLIST_ENTRY* Entry
)
{
Entry->Next = ListHead->Next;
ListHead->Next = Entry;
}
FORCEINLINE
CXPLAT_SLIST_ENTRY*
CxPlatListPopEntry(
_Inout_ CXPLAT_SLIST_ENTRY* ListHead
)
{
CXPLAT_SLIST_ENTRY* FirstEntry = ListHead->Next;
if (FirstEntry != NULL) {
ListHead->Next = FirstEntry->Next;
}
return FirstEntry;
}
#include "quic_hashtable.h"
#include "quic_toeplitz.h"
#ifdef DEBUG
void
CxPlatSetAllocFailDenominator(
_In_ int32_t Value
);
int32_t
CxPlatGetAllocFailDenominator(
);
#endif
#ifdef DEBUG
#define CxPlatIsRandomMemoryFailureEnabled() (CxPlatGetAllocFailDenominator() != 0)
#else
#define CxPlatIsRandomMemoryFailureEnabled() (FALSE)
#endif
//
// General purpose execution context abstraction layer. Used for driving worker
// loops.
//
typedef struct QUIC_EXECUTION QUIC_EXECUTION;
typedef struct QUIC_GLOBAL_EXECUTION_CONFIG QUIC_GLOBAL_EXECUTION_CONFIG;
typedef struct QUIC_EXECUTION_CONFIG QUIC_EXECUTION_CONFIG;
typedef struct CXPLAT_EXECUTION_CONTEXT CXPLAT_EXECUTION_CONTEXT;
typedef struct CXPLAT_EXECUTION_STATE {
uint64_t TimeNow; // in microseconds
uint64_t LastWorkTime; // in microseconds
uint64_t LastPoolProcessTime; // in microseconds
uint32_t WaitTime;
uint32_t NoWorkCount;
CXPLAT_THREAD_ID ThreadID;
} CXPLAT_EXECUTION_STATE;
typedef struct CXPLAT_WORKER_POOL CXPLAT_WORKER_POOL;
#ifndef _KERNEL_MODE
//
// Worker pool API used for driving execution contexts
//
//
// Different references on a worker pool.
//
typedef enum CXPLAT_WORKER_POOL_REF {
CXPLAT_WORKER_POOL_REF_EXTERNAL, // Created by ExecutionCreate
CXPLAT_WORKER_POOL_REF_LIBRARY, // Created by MsQuic
CXPLAT_WORKER_POOL_REF_EPOLL,
CXPLAT_WORKER_POOL_REF_IOURING,
CXPLAT_WORKER_POOL_REF_KQUEUE,
CXPLAT_WORKER_POOL_REF_RAW,
CXPLAT_WORKER_POOL_REF_WINSOCK,
CXPLAT_WORKER_POOL_REF_TOOL,
CXPLAT_WORKER_POOL_REF_COUNT
} CXPLAT_WORKER_POOL_REF;
CXPLAT_WORKER_POOL*
CxPlatWorkerPoolCreate(
_In_opt_ QUIC_GLOBAL_EXECUTION_CONFIG* Config,
_In_ CXPLAT_WORKER_POOL_REF RefType
);
_Success_(return != NULL)
CXPLAT_WORKER_POOL*
CxPlatWorkerPoolCreateExternal(
_In_ uint32_t Count,
_In_reads_(Count) QUIC_EXECUTION_CONFIG* Configs,
_Out_writes_(Count) QUIC_EXECUTION** Executions
);
void
CxPlatWorkerPoolDelete(
_In_opt_ CXPLAT_WORKER_POOL* WorkerPool,
_In_ CXPLAT_WORKER_POOL_REF RefType
);
uint32_t
CxPlatWorkerPoolGetCount(
_In_ CXPLAT_WORKER_POOL* WorkerPool
);
BOOLEAN
CxPlatWorkerPoolAddRef(
_In_ CXPLAT_WORKER_POOL* WorkerPool,
_In_ CXPLAT_WORKER_POOL_REF RefType
);
void
CxPlatWorkerPoolRelease(
_In_ CXPLAT_WORKER_POOL* WorkerPool,
_In_ CXPLAT_WORKER_POOL_REF RefType
);
uint32_t
CxPlatWorkerPoolGetIdealProcessor(
_In_ CXPLAT_WORKER_POOL* WorkerPool,
_In_ uint32_t Index // Into the worker pool
);
CXPLAT_EVENTQ*
CxPlatWorkerPoolGetEventQ(
_In_ CXPLAT_WORKER_POOL* WorkerPool,
_In_ uint16_t Index // Into the worker pool
);
void
CxPlatWorkerPoolAddExecutionContext(
_In_ CXPLAT_WORKER_POOL* WorkerPool,
_Inout_ CXPLAT_EXECUTION_CONTEXT* Context,
_In_ uint16_t Index // Into the worker pool
);
uint32_t
CxPlatWorkerPoolWorkerPoll(
_In_ QUIC_EXECUTION* Execution
);
typedef struct CXPLAT_WORKER_STATISTICS {
uint64_t CumulativeActiveTimeUs; // Time the worker spent active (not idle).
uint64_t CumulativeWallTimeUs; // Wall time since the worker thread started.
uint16_t IdealProcessor; // CPU the worker is affinitized to.
} CXPLAT_WORKER_STATISTICS;
//
// Gets the statistics for a worker in the pool
//
void
CxPlatWorkerPoolGetStatistics(
_In_ CXPLAT_WORKER_POOL* WorkerPool,
_In_ uint32_t Index,
_Out_ CXPLAT_WORKER_STATISTICS* Stats
);
//
// Supports more dynamic operations, but must be submitted to the platform worker
// to manage.
//
typedef struct CXPLAT_POOL_EX {
CXPLAT_POOL Base;
CXPLAT_LIST_ENTRY Link;
void* Owner;
} CXPLAT_POOL_EX;
void
CxPlatAddDynamicPoolAllocator(
_In_ CXPLAT_WORKER_POOL* WorkerPool,
_Inout_ CXPLAT_POOL_EX* Pool,
_In_ uint16_t Index // Into the execution config processor array
);
void
CxPlatRemoveDynamicPoolAllocator(
_Inout_ CXPLAT_POOL_EX* Pool
);
#endif // !_KERNEL_MODE
//
// Returns FALSE when it's time to cleanup.
//
typedef
_IRQL_requires_max_(PASSIVE_LEVEL)
BOOLEAN
(*CXPLAT_EXECUTION_FN)(
_Inout_ void* Context,
_Inout_ CXPLAT_EXECUTION_STATE* State
);
typedef struct CXPLAT_EXECUTION_CONTEXT {
CXPLAT_SLIST_ENTRY Entry;
void* Context;
void* CxPlatContext;
CXPLAT_EXECUTION_FN Callback;
uint64_t NextTimeUs;
volatile BOOLEAN Ready;
} CXPLAT_EXECUTION_CONTEXT;
#ifdef _KERNEL_MODE // Not supported on kernel mode
#define CxPlatWakeExecutionContext(Context) CXPLAT_FRE_ASSERT(FALSE)
#if DEBUG
#define CxPlatWorkerIsThisThread(Context) TRUE
#else
#define CxPlatWorkerIsThisThread(Context) CXPLAT_FRE_ASSERT(FALSE)
#endif
#else // _KERNEL_MODE
void
CxPlatWakeExecutionContext(
_In_ CXPLAT_EXECUTION_CONTEXT* Context
);
BOOLEAN
CxPlatWorkerIsThisThread(
_In_ CXPLAT_EXECUTION_CONTEXT* Context
);
#endif // _KERNEL_MODE
//
// Test Interface for loading a self-signed certificate.
//
#ifdef QUIC_TEST_APIS
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct QUIC_CREDENTIAL_CONFIG QUIC_CREDENTIAL_CONFIG;
typedef struct QUIC_CERTIFICATE_HASH QUIC_CERTIFICATE_HASH;
typedef struct QUIC_CERTIFICATE_HASH_STORE QUIC_CERTIFICATE_HASH_STORE;
typedef struct QUIC_CERTIFICATE_FILE QUIC_CERTIFICATE_FILE;
typedef struct QUIC_CERTIFICATE_FILE_PROTECTED QUIC_CERTIFICATE_FILE_PROTECTED;
typedef struct QUIC_CERTIFICATE_PKCS12 QUIC_CERTIFICATE_PKCS12;
typedef enum CXPLAT_SELF_SIGN_CERT_TYPE {
CXPLAT_SELF_SIGN_CERT_USER,
CXPLAT_SELF_SIGN_CERT_MACHINE,
CXPLAT_SELF_SIGN_CA_CERT_USER,
CXPLAT_SELF_SIGN_CA_CERT_MACHINE
} CXPLAT_SELF_SIGN_CERT_TYPE;
typedef enum CXPLAT_TEST_CERT_TYPE {
CXPLAT_TEST_CERT_VALID_SERVER,
CXPLAT_TEST_CERT_VALID_CLIENT,
CXPLAT_TEST_CERT_EXPIRED_SERVER,
CXPLAT_TEST_CERT_EXPIRED_CLIENT,
CXPLAT_TEST_CERT_SELF_SIGNED_SERVER,
CXPLAT_TEST_CERT_SELF_SIGNED_CLIENT,
CXPLAT_TEST_CERT_CA_SERVER,
CXPLAT_TEST_CERT_CA_CLIENT,
} CXPLAT_TEST_CERT_TYPE;
_IRQL_requires_max_(PASSIVE_LEVEL)
const char*
CxPlatGetSelfSignedCertCaCertificateFileName(
_In_ BOOLEAN ClientCertificate
);
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_CREDENTIAL_CONFIG*
CxPlatGetSelfSignedCert(
_In_ CXPLAT_SELF_SIGN_CERT_TYPE Type,
_In_ BOOLEAN ClientCertificate,
_In_z_ const char* CaCertificateFile
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Success_(return == TRUE)
BOOLEAN
CxPlatGetTestCertificate(
_In_ CXPLAT_TEST_CERT_TYPE Type,
_In_ CXPLAT_SELF_SIGN_CERT_TYPE StoreType,
_In_ uint32_t CredType,
_Out_ QUIC_CREDENTIAL_CONFIG* Params,
_When_(CredType == QUIC_CREDENTIAL_TYPE_CERTIFICATE_HASH, _Out_)
_When_(CredType != QUIC_CREDENTIAL_TYPE_CERTIFICATE_HASH, _Reserved_)
QUIC_CERTIFICATE_HASH* CertHash,
_When_(CredType == QUIC_CREDENTIAL_TYPE_CERTIFICATE_HASH_STORE, _Out_)
_When_(CredType != QUIC_CREDENTIAL_TYPE_CERTIFICATE_HASH_STORE, _Reserved_)
QUIC_CERTIFICATE_HASH_STORE* CertHashStore,
_When_(CredType == QUIC_CREDENTIAL_TYPE_CERTIFICATE_FILE, _Out_)
_When_(CredType != QUIC_CREDENTIAL_TYPE_CERTIFICATE_FILE, _Reserved_)
QUIC_CERTIFICATE_FILE* CertFile,
_When_(CredType == QUIC_CREDENTIAL_TYPE_CERTIFICATE_FILE_PROTECTED, _Out_)
_When_(CredType != QUIC_CREDENTIAL_TYPE_CERTIFICATE_FILE_PROTECTED, _Reserved_)
QUIC_CERTIFICATE_FILE_PROTECTED* CertFileProtected,
_When_(CredType == QUIC_CREDENTIAL_TYPE_CERTIFICATE_PKCS12, _Out_)
_When_(CredType != QUIC_CREDENTIAL_TYPE_CERTIFICATE_PKCS12, _Reserved_)
QUIC_CERTIFICATE_PKCS12* Pkcs12,
_When_(CredType == QUIC_CREDENTIAL_TYPE_NONE, _Out_z_bytecap_(100))
_When_(CredType != QUIC_CREDENTIAL_TYPE_NONE, _Reserved_)
char Principal[100]
);
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatFreeSelfSignedCert(
_In_ const QUIC_CREDENTIAL_CONFIG* CredConfig
);
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatFreeSelfSignedCertCaFile(
_In_z_ const char* CaFile
);
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatFreeTestCert(
_In_ QUIC_CREDENTIAL_CONFIG* Params
);
#if defined(__cplusplus)
}
#endif
#endif // QUIC_TEST_APIS
#if defined(__cplusplus)
}
#endif