Add support for tracking process owning connection. (#1865)

This commit is contained in:
Anthony Rossi 2021-08-04 00:14:52 -07:00 коммит произвёл GitHub
Родитель dcb1bd4730
Коммит baefc0b247
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
18 изменённых файлов: 133 добавлений и 117 удалений

Просмотреть файл

@ -36,14 +36,7 @@ CXPLAT_STATIC_ASSERT(
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicBindingInitialize(
#ifdef QUIC_COMPARTMENT_ID
_In_ QUIC_COMPARTMENT_ID CompartmentId,
#endif
_In_ BOOLEAN ShareBinding,
_In_ BOOLEAN ServerOwned,
_In_opt_ const QUIC_ADDR* LocalAddress,
_In_ const uint32_t LocalInterface,
_In_opt_ const QUIC_ADDR* RemoteAddress,
_In_ const CXPLAT_UDP_CONFIG* UdpConfig,
_Out_ QUIC_BINDING** NewBinding
)
{
@ -63,9 +56,9 @@ QuicBindingInitialize(
}
Binding->RefCount = 0; // No refs until it's added to the library's list
Binding->Exclusive = !ShareBinding;
Binding->ServerOwned = ServerOwned;
Binding->Connected = RemoteAddress == NULL ? FALSE : TRUE;
Binding->Exclusive = !(UdpConfig->Flags & CXPLAT_SOCKET_FLAG_SHARE);
Binding->ServerOwned = !!(UdpConfig->Flags & CXPLAT_SOCKET_SERVER_OWNED);
Binding->Connected = UdpConfig->RemoteAddress == NULL ? FALSE : TRUE;
Binding->StatelessOperCount = 0;
CxPlatDispatchRwLockInitialize(&Binding->RwLock);
CxPlatDispatchLockInitialize(&Binding->StatelessOperLock);
@ -87,12 +80,12 @@ QuicBindingInitialize(
QUIC_VERSION_RESERVED;
#ifdef QUIC_COMPARTMENT_ID
Binding->CompartmentId = CompartmentId;
Binding->CompartmentId = UdpConfig->CompartmentId;
BOOLEAN RevertCompartmentId = FALSE;
QUIC_COMPARTMENT_ID PrevCompartmentId = QuicCompartmentIdGetCurrent();
if (PrevCompartmentId != CompartmentId) {
Status = QuicCompartmentIdSetCurrent(CompartmentId);
if (PrevCompartmentId != UdpConfig->CompartmentId) {
Status = QuicCompartmentIdSetCurrent(UdpConfig->CompartmentId);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
BindingErrorStatus,
@ -108,44 +101,37 @@ QuicBindingInitialize(
#if QUIC_TEST_DATAPATH_HOOKS_ENABLED
QUIC_TEST_DATAPATH_HOOKS* Hooks = MsQuicLib.TestDatapathHooks;
CXPLAT_UDP_CONFIG HookUdpConfig = *UdpConfig;
if (Hooks != NULL) {
QUIC_ADDR RemoteAddressCopy;
if (RemoteAddress != NULL) {
RemoteAddressCopy = *RemoteAddress;
if (UdpConfig->RemoteAddress != NULL) {
RemoteAddressCopy = *UdpConfig->RemoteAddress;
}
QUIC_ADDR LocalAddressCopy;
if (LocalAddress != NULL) {
LocalAddressCopy = *LocalAddress;
if (UdpConfig->LocalAddress != NULL) {
LocalAddressCopy = *UdpConfig->LocalAddress;
}
Hooks->Create(
RemoteAddress != NULL ? &RemoteAddressCopy : NULL,
LocalAddress != NULL ? &LocalAddressCopy : NULL);
UdpConfig->RemoteAddress != NULL ? &RemoteAddressCopy : NULL,
UdpConfig->LocalAddress != NULL ? &LocalAddressCopy : NULL);
CXPLAT_UDP_CONFIG UdpConfig;
UdpConfig.LocalAddress = LocalAddress != NULL ? &LocalAddressCopy : NULL;
UdpConfig.RemoteAddress = RemoteAddress != NULL ? &RemoteAddressCopy : NULL;
UdpConfig.Flags = ShareBinding ? CXPLAT_SOCKET_FLAG_SHARE : 0;
UdpConfig.InterfaceIndex = LocalInterface;
UdpConfig.CallbackContext = Binding;
HookUdpConfig.LocalAddress = (UdpConfig->LocalAddress != NULL) ? &LocalAddressCopy : NULL;
HookUdpConfig.RemoteAddress = (UdpConfig->RemoteAddress != NULL) ? &RemoteAddressCopy : NULL;
HookUdpConfig.CallbackContext = Binding;
Status =
CxPlatSocketCreateUdp(
MsQuicLib.Datapath,
&UdpConfig,
&HookUdpConfig,
&Binding->Socket);
} else {
#endif
CXPLAT_UDP_CONFIG UdpConfig;
UdpConfig.LocalAddress = LocalAddress;
UdpConfig.RemoteAddress = RemoteAddress;
UdpConfig.Flags = ShareBinding ? CXPLAT_SOCKET_FLAG_SHARE : 0;
UdpConfig.InterfaceIndex = LocalInterface;
UdpConfig.CallbackContext = Binding;
((CXPLAT_UDP_CONFIG*)UdpConfig)->CallbackContext = Binding;
Status =
CxPlatSocketCreateUdp(
MsQuicLib.Datapath,
&UdpConfig,
UdpConfig,
&Binding->Socket);
#if QUIC_TEST_DATAPATH_HOOKS_ENABLED
}

Просмотреть файл

@ -254,14 +254,7 @@ CXPLAT_DATAPATH_UNREACHABLE_CALLBACK QuicBindingUnreachable;
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicBindingInitialize(
#ifdef QUIC_COMPARTMENT_ID
_In_ QUIC_COMPARTMENT_ID CompartmentId,
#endif
_In_ BOOLEAN ShareBinding,
_In_ BOOLEAN ServerOwned,
_In_opt_ const QUIC_ADDR* LocalAddress,
_In_ const uint32_t LocalInterface,
_In_opt_ const QUIC_ADDR* RemoteAddress,
_In_ const CXPLAT_UDP_CONFIG* UdpConfig,
_Out_ QUIC_BINDING** NewBinding
);

Просмотреть файл

@ -145,6 +145,11 @@ MsQuicConfigurationOpen(
}
#endif
#ifdef QUIC_OWNING_PROCESS
Configuration->OwningProcess = QuicProcessGetCurrentProcess();
QuicProcessAddRef(Configuration->OwningProcess);
#endif
if (Registration->AppNameLength != 0) {
char SpecificAppKey[UINT8_MAX + sizeof(QUIC_SETTING_APP_KEY)] = QUIC_SETTING_APP_KEY;
CxPlatCopyMemory(
@ -244,6 +249,10 @@ QuicConfigurationUninitialize(
QuicSiloRelease(Configuration->Silo);
#endif
#ifdef QUIC_OWNING_PROCESS
QuicProcessRelease(Configuration->OwningProcess);
#endif
QuicSettingsCleanup(&Configuration->Settings);
CxPlatRundownRelease(&Configuration->Registration->Rundown);

Просмотреть файл

@ -50,6 +50,13 @@ typedef struct QUIC_CONFIGURATION {
//
CXPLAT_STORAGE* Storage; // Only necessary if it could be in a different silo.
#endif
#ifdef QUIC_OWNING_PROCESS
//
// The process token of the owning process
//
QUIC_PROCESS OwningProcess;
#endif
CXPLAT_STORAGE* AppSpecificStorage;
//

Просмотреть файл

@ -1816,19 +1816,24 @@ QuicConnStart(
Connection,
CASTED_CLOG_BYTEARRAY(sizeof(Path->RemoteAddress), &Path->RemoteAddress));
CXPLAT_UDP_CONFIG UdpConfig = {0};
UdpConfig.LocalAddress = Connection->State.LocalAddressSet ? &Path->LocalAddress : NULL;
UdpConfig.RemoteAddress = &Path->RemoteAddress;
UdpConfig.Flags = Connection->State.ShareBinding ? CXPLAT_SOCKET_FLAG_SHARE : 0;
UdpConfig.InterfaceIndex = Connection->State.LocalInterfaceSet ? (uint32_t)Path->LocalAddress.Ipv6.sin6_scope_id : 0, // NOLINT(google-readability-casting)
#ifdef QUIC_COMPARTMENT_ID
UdpConfig.CompartmentId = Configuration->CompartmentId;
#endif
#ifdef QUIC_OWNING_PROCESS
UdpConfig.OwningProcess = Configuration->OwningProcess;
#endif
//
// Get the binding for the current local & remote addresses.
//
Status =
QuicLibraryGetBinding(
#ifdef QUIC_COMPARTMENT_ID
Configuration->CompartmentId,
#endif
Connection->State.ShareBinding,
FALSE,
Connection->State.LocalAddressSet ? &Path->LocalAddress : NULL,
Connection->State.LocalInterfaceSet ? (uint32_t)Path->LocalAddress.Ipv6.sin6_scope_id : 0, // NOLINT(google-readability-casting)
&Path->RemoteAddress,
&UdpConfig,
&Path->Binding);
if (QUIC_FAILED(Status)) {
goto Exit;
@ -5711,16 +5716,21 @@ QuicConnParamSet(
QUIC_BINDING* OldBinding = Connection->Paths[0].Binding;
CXPLAT_UDP_CONFIG UdpConfig = {0};
UdpConfig.LocalAddress = LocalAddress;
UdpConfig.RemoteAddress = &Connection->Paths[0].RemoteAddress;
UdpConfig.Flags = Connection->State.ShareBinding ? CXPLAT_SOCKET_FLAG_SHARE : 0;
UdpConfig.InterfaceIndex = 0;
#ifdef QUIC_COMPARTMENT_ID
UdpConfig.CompartmentId = Connection->Configuration->CompartmentId;
#endif
#ifdef QUIC_OWNING_PROCESS
UdpConfig.OwningProcess = Connection->Configuration->OwningProcess;
#endif
Status =
QuicLibraryGetBinding(
#ifdef QUIC_COMPARTMENT_ID
Connection->Configuration->CompartmentId,
#endif
Connection->State.ShareBinding,
FALSE,
LocalAddress,
0,
&Connection->Paths[0].RemoteAddress,
&UdpConfig,
&Connection->Paths[0].Binding);
if (QUIC_FAILED(Status)) {
Connection->Paths[0].Binding = OldBinding;

Просмотреть файл

@ -1476,21 +1476,16 @@ QuicLibraryLookupBinding(
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicLibraryGetBinding(
#ifdef QUIC_COMPARTMENT_ID
_In_ QUIC_COMPARTMENT_ID CompartmentId,
#endif
_In_ BOOLEAN ShareBinding,
_In_ BOOLEAN ServerOwned,
_In_opt_ const QUIC_ADDR* LocalAddress,
_In_ const uint32_t LocalInterface,
_In_opt_ const QUIC_ADDR* RemoteAddress,
_In_ const CXPLAT_UDP_CONFIG* UdpConfig,
_Out_ QUIC_BINDING** NewBinding
)
{
QUIC_STATUS Status;
QUIC_BINDING* Binding;
QUIC_ADDR NewLocalAddress;
BOOLEAN PortUnspecified = LocalAddress == NULL || QuicAddrGetPort(LocalAddress) == 0;
BOOLEAN PortUnspecified = UdpConfig->LocalAddress == NULL || QuicAddrGetPort(UdpConfig->LocalAddress) == 0;
BOOLEAN ShareBinding = !!(UdpConfig->Flags & CXPLAT_SOCKET_FLAG_SHARE);
BOOLEAN ServerOwned = !!(UdpConfig->Flags & CXPLAT_SOCKET_SERVER_OWNED);
#ifdef QUIC_SHARED_EPHEMERAL_WORKAROUND
//
@ -1525,10 +1520,10 @@ SharedEphemeralRetry:
Binding =
QuicLibraryLookupBinding(
#ifdef QUIC_COMPARTMENT_ID
CompartmentId,
UdpConfig->CompartmentId,
#endif
LocalAddress,
RemoteAddress);
UdpConfig->LocalAddress,
UdpConfig->RemoteAddress);
if (Binding != NULL) {
if (!ShareBinding || Binding->Exclusive ||
(ServerOwned != Binding->ServerOwned)) {
@ -1558,8 +1553,8 @@ SharedEphemeralRetry:
if (Status != QUIC_STATUS_NOT_FOUND) {
#ifdef QUIC_SHARED_EPHEMERAL_WORKAROUND
if (QUIC_FAILED(Status) && SharedEphemeralWorkAround) {
CXPLAT_DBG_ASSERT(LocalAddress);
QuicAddrSetPort((QUIC_ADDR*)LocalAddress, QuicAddrGetPort(LocalAddress) + 1);
CXPLAT_DBG_ASSERT(UdpConfig->LocalAddress);
QuicAddrSetPort((QUIC_ADDR*)UdpConfig->LocalAddress, QuicAddrGetPort(UdpConfig->LocalAddress) + 1);
goto SharedEphemeralRetry;
}
#endif // QUIC_SHARED_EPHEMERAL_WORKAROUND
@ -1574,20 +1569,13 @@ NewBinding:
Status =
QuicBindingInitialize(
#ifdef QUIC_COMPARTMENT_ID
CompartmentId,
#endif
ShareBinding,
ServerOwned,
LocalAddress,
LocalInterface,
RemoteAddress,
UdpConfig,
NewBinding);
if (QUIC_FAILED(Status)) {
#ifdef QUIC_SHARED_EPHEMERAL_WORKAROUND
if (SharedEphemeralWorkAround) {
CXPLAT_DBG_ASSERT(LocalAddress);
QuicAddrSetPort((QUIC_ADDR*)LocalAddress, QuicAddrGetPort(LocalAddress) + 1);
CXPLAT_DBG_ASSERT(UdpConfig->LocalAddress);
QuicAddrSetPort((QUIC_ADDR*)UdpConfig->LocalAddress, QuicAddrGetPort(UdpConfig->LocalAddress) + 1);
goto SharedEphemeralRetry;
}
#endif // QUIC_SHARED_EPHEMERAL_WORKAROUND
@ -1613,10 +1601,10 @@ NewBinding:
Binding =
QuicLibraryLookupBinding(
#ifdef QUIC_COMPARTMENT_ID
CompartmentId,
UdpConfig->CompartmentId,
#endif
&NewLocalAddress,
RemoteAddress);
UdpConfig->RemoteAddress);
} else {
//
// The datapath does not supports multiple connected sockets on the same
@ -1626,7 +1614,7 @@ NewBinding:
Binding =
QuicLibraryLookupBinding(
#ifdef QUIC_COMPARTMENT_ID
CompartmentId,
UdpConfig->CompartmentId,
#endif
&NewLocalAddress,
NULL);
@ -1678,8 +1666,8 @@ NewBinding:
// one.
//
SharedEphemeralWorkAround = TRUE;
LocalAddress = &NewLocalAddress;
QuicAddrSetPort((QUIC_ADDR*)LocalAddress, QuicAddrGetPort(LocalAddress) + 1);
((CXPLAT_UDP_CONFIG*)UdpConfig)->LocalAddress = &NewLocalAddress;
QuicAddrSetPort((QUIC_ADDR*)UdpConfig->LocalAddress, QuicAddrGetPort(UdpConfig->LocalAddress) + 1);
goto SharedEphemeralRetry;
#else
Status = QUIC_STATUS_INTERNAL_ERROR;
@ -1695,8 +1683,8 @@ NewBinding:
*NewBinding = NULL;
#ifdef QUIC_SHARED_EPHEMERAL_WORKAROUND
if (SharedEphemeralWorkAround) {
CXPLAT_DBG_ASSERT(LocalAddress);
QuicAddrSetPort((QUIC_ADDR*)LocalAddress, QuicAddrGetPort(LocalAddress) + 1);
CXPLAT_DBG_ASSERT(UdpConfig->LocalAddress);
QuicAddrSetPort((QUIC_ADDR*)UdpConfig->LocalAddress, QuicAddrGetPort(UdpConfig->LocalAddress) + 1);
goto SharedEphemeralRetry;
}
#endif // QUIC_SHARED_EPHEMERAL_WORKAROUND

Просмотреть файл

@ -490,14 +490,7 @@ QuicLibraryGetParam(
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicLibraryGetBinding(
#ifdef QUIC_COMPARTMENT_ID
_In_ QUIC_COMPARTMENT_ID CompartmentId,
#endif
_In_ BOOLEAN ShareBinding,
_In_ BOOLEAN ServerOwned,
_In_opt_ const QUIC_ADDR* LocalAddress,
_In_ const uint32_t LocalInterface,
_In_opt_ const QUIC_ADDR* RemoteAddress,
_In_ const CXPLAT_UDP_CONFIG* UdpConfig,
_Out_ QUIC_BINDING** NewBinding
);

Просмотреть файл

@ -258,17 +258,22 @@ MsQuicListenerStart(
goto Error;
}
CXPLAT_UDP_CONFIG UdpConfig = {0};
UdpConfig.LocalAddress = &BindingLocalAddress;
UdpConfig.RemoteAddress = NULL;
UdpConfig.Flags = CXPLAT_SOCKET_FLAG_SHARE | CXPLAT_SOCKET_SERVER_OWNED; // Listeners always share the binding.
UdpConfig.InterfaceIndex = 0;
#ifdef QUIC_COMPARTMENT_ID
UdpConfig.CompartmentId = QuicCompartmentIdGetCurrent();
#endif
#ifdef QUIC_OWNING_PROCESS
UdpConfig.OwningProcess = NULL; // Owning process not supported for listeners.
#endif
CXPLAT_TEL_ASSERT(Listener->Binding == NULL);
Status =
QuicLibraryGetBinding(
#ifdef QUIC_COMPARTMENT_ID
QuicCompartmentIdGetCurrent(),
#endif
TRUE, // Listeners always share the binding.
TRUE,
&BindingLocalAddress,
0,
NULL,
&UdpConfig,
&Listener->Binding);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(

Просмотреть файл

@ -436,13 +436,20 @@ CxPlatDataPathGetGatewayAddresses(
#define CXPLAT_SOCKET_FLAG_PCP 0x00000001 // Socket is used for internal PCP support
#define CXPLAT_SOCKET_FLAG_SHARE 0x00000002 // Forces sharing of the address and port
#define CXPLAT_SOCKET_SERVER_OWNED 0x00000004 // Indicates socket is a listener socket
typedef struct CXPLAT_UDP_CONFIG {
const QUIC_ADDR* LocalAddress; // optional
const QUIC_ADDR* RemoteAddress; // optional
uint32_t Flags; // CXPLAT_SOCKET_FLAG_*
uint32_t InterfaceIndex; // 0 means any/all
void* CallbackContext; // optional
const QUIC_ADDR* LocalAddress; // optional
const QUIC_ADDR* RemoteAddress; // optional
uint32_t Flags; // CXPLAT_SOCKET_FLAG_*
uint32_t InterfaceIndex; // 0 means any/all
void* CallbackContext; // optional
#ifdef QUIC_COMPARTMENT_ID
QUIC_COMPARTMENT_ID CompartmentId; // optional
#endif
#ifdef QUIC_OWNING_PROCESS
QUIC_PROCESS OwningProcess; // Kernel client-only
#endif
} CXPLAT_UDP_CONFIG;
//

Просмотреть файл

@ -134,6 +134,7 @@ typedef struct CXPLAT_SLIST_ENTRY {
#define QUIC_POOL_DESIRED_VER_LIST '04cQ' // Qc40 - QUIC App-supplied desired versions list
#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

Просмотреть файл

@ -848,6 +848,17 @@ CxPlatRandom(
_Out_writes_bytes_(BufferLen) void* Buffer
);
//
// Process object abstraction
//
#define QUIC_OWNING_PROCESS 1
#define QUIC_PROCESS PEPROCESS
#define QuicProcessGetCurrentProcess() ((QUIC_PROCESS)PsGetCurrentProcess())
#define QuicProcessAddRef(Process) if (Process != NULL) { ObReferenceObjectWithTag(Process, QUIC_POOL_PROCESS); }
#define QuicProcessRelease(Process) if (Process != NULL) { ObDereferenceObjectWithTag(Process, QUIC_POOL_PROCESS); }
//
// Silo interfaces
//

Просмотреть файл

@ -134,12 +134,15 @@ QuicMainStart(
}
QuicAddr LocalAddress {QUIC_ADDRESS_FAMILY_INET, (uint16_t)9999};
CXPLAT_UDP_CONFIG UdpConfig;
CXPLAT_UDP_CONFIG UdpConfig = {0};
UdpConfig.LocalAddress = &LocalAddress.SockAddr;
UdpConfig.RemoteAddress = nullptr;
UdpConfig.Flags = 0;
UdpConfig.InterfaceIndex = 0;
UdpConfig.CallbackContext = StopEvent;
#ifdef QUIC_OWNING_PROCESS
UdpConfig.OwningProcess = QuicProcessGetCurrentProcess();
#endif
Status = CxPlatSocketCreateUdp(Datapath, &UdpConfig, &Binding);
if (QUIC_FAILED(Status)) {

Просмотреть файл

@ -1460,7 +1460,7 @@ CxPlatSocketCreateUdp(
WSK_FLAG_DATAGRAM_SOCKET,
Binding,
&Datapath->WskDispatch,
NULL,
Config->OwningProcess,
NULL,
NULL,
&Binding->Irp);

Просмотреть файл

@ -178,7 +178,7 @@ CxPlatPcpInitialize(
PcpContext->ClientCallback = Handler;
PcpContext->GatewayCount = GatewayAddressesCount;
CXPLAT_UDP_CONFIG UdpConfig;
CXPLAT_UDP_CONFIG UdpConfig = {0};
UdpConfig.LocalAddress = NULL;
UdpConfig.Flags = CXPLAT_SOCKET_FLAG_PCP;
UdpConfig.InterfaceIndex = 0;

Просмотреть файл

@ -434,7 +434,7 @@ struct CxPlatSocket {
_In_ uint32_t InternalFlags = 0
) noexcept
{
CXPLAT_UDP_CONFIG UdpConfig;
CXPLAT_UDP_CONFIG UdpConfig = {0};
UdpConfig.LocalAddress = LocalAddress;
UdpConfig.RemoteAddress = RemoteAddress;
UdpConfig.Flags = InternalFlags;

Просмотреть файл

@ -164,12 +164,15 @@ struct DrillSender {
ServerAddress.Ipv6.sin6_port = NetworkPort;
}
CXPLAT_UDP_CONFIG UdpConfig;
CXPLAT_UDP_CONFIG UdpConfig = {0};
UdpConfig.LocalAddress = nullptr;
UdpConfig.RemoteAddress = &ServerAddress;
UdpConfig.Flags = 0;
UdpConfig.InterfaceIndex = 0;
UdpConfig.CallbackContext = this;
#ifdef QUIC_OWNING_PROCESS
UdpConfig.OwningProcess = QuicProcessGetCurrentProcess();
#endif
Status =
CxPlatSocketCreateUdp(

Просмотреть файл

@ -300,7 +300,7 @@ void RunAttackValidInitial(CXPLAT_SOCKET* Binding)
CXPLAT_THREAD_CALLBACK(RunAttackThread, /* Context */)
{
CXPLAT_SOCKET* Binding;
CXPLAT_UDP_CONFIG UdpConfig;
CXPLAT_UDP_CONFIG UdpConfig = {0};
UdpConfig.LocalAddress = nullptr;
UdpConfig.RemoteAddress = &ServerAddress;
UdpConfig.Flags = 0;

Просмотреть файл

@ -29,7 +29,7 @@ struct LbInterface {
QUIC_ADDR LocalAddress;
LbInterface(_In_ const QUIC_ADDR* Address, bool IsPublic) : IsPublic(IsPublic) {
CXPLAT_UDP_CONFIG UdpConfig;
CXPLAT_UDP_CONFIG UdpConfig = {0};
UdpConfig.LocalAddress = nullptr;
UdpConfig.RemoteAddress = nullptr;
UdpConfig.Flags = 0;