зеркало из https://github.com/microsoft/msquic.git
Unify datapath (#3819)
* Remove QUIC_USE_RAW_DATAPATH (logic only) * move logic to core side * remove QUIC_USE_RAW_DATAPATH from test * fix googletest version and add last line * replace from flag to function call * fix build error * fix build/test issues * implement CxPlatResolveRoute for normal socket * add Getter of Datapath feature * fix build issues * adopt comments * adopt comment and fix kernel build error * fix kernel build error * more fix for kernel build * Unify datapath * DatapathTest partially work * just unify build of both normal socket and xdp * SOCKET: RAW{...Socket{BASE{addr}}}, DATAPATH: XDP{RAW{DATAPATH*}} <-> DATAPATH{RAW*, BASE{callbacks}} * tmp * add preview_feature flag back * refactoring CxPlatIsRouteReady * fix linux code check * adjust func names * fix comments * fix IsRouteReady and clean ifdef for _KERNEL_MODE * kernel build error * Set RouteResolved for Rx * fix more tests * move global definition in header file * kernel to avoid calling helper function * move QuitTestIsFeatureSupported after RegistrationOpen * supress warning * remove QuitTestIsFeatureSupported from quic_gtest as it doesn't work as expected by dependency of MsQuicLib.Datapath * remove raw feature check as much as possible * ifdef for UseQTIP visibility * tmp * tmp * fix merge side effects * all tests passed * fix tests in msquicplatformtest * fix tcp with duonic * update clog * use xdp v1 * WIP cleanup * refactoring CXPLAT_SEND_DATA * remove mangling and function pointer * remove unnecessary change in test * fix comments * cleanup * move logic to _winuser * use dummy raw datapath for uwp build * dummy raw * remove double free * fix comments * update dummy func * fix perf run for TCP * partially fix comments * fix build error for uwp and remove duplicate variable in raw socket * set socket before start receiving * add dummy to clog * add clog files for dummy * fix dependency for cargo on windows * remove dummy clog files * remove AuxSocket * add pwsh for cargo setup * clog fix * add include dir for cargo * [WIP] fix cargo and qtip * fix clog, qtip, rename private raw functions and cleanup * experiment to avoid write overflow * use Config->Route->DatapathType for data allocation * more strict if conditions * fix comments * fix uwp build * fix clog and artifact name * fix back xdp dependency * Simply build automation * missed one * apply unification to linux and remove QUIC_USE_XDP flag * move types to any platform * add abstruction layer for linux * add clog * add clog dependencies * fix CodeCheck issues * remove xdp specific artifact dir name and always install xdp deps * add docs * More Fixes for XDP in automation (mostly OneBranch) --------- Co-authored-by: Nick Banks <nibanks@microsoft.com>
This commit is contained in:
Родитель
f9d26ac7c0
Коммит
ae3db5cd99
|
@ -86,22 +86,6 @@ extends:
|
|||
parameters:
|
||||
config: Debug
|
||||
|
||||
- stage: build_windows_xdp
|
||||
displayName: Build Windows XDP
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: .azure/obtemplates/build-winuser-xdp.yml@self
|
||||
parameters:
|
||||
config: Release
|
||||
tls: schannel
|
||||
- template: .azure/obtemplates/build-winuser-xdp.yml@self
|
||||
parameters:
|
||||
config: Release
|
||||
tls: openssl
|
||||
- template: .azure/obtemplates/build-winuser-xdp.yml@self
|
||||
parameters:
|
||||
config: Debug
|
||||
|
||||
- stage: build_windows
|
||||
displayName: Build Windows
|
||||
dependsOn: []
|
||||
|
@ -204,7 +188,6 @@ extends:
|
|||
dependsOn:
|
||||
- build_windows
|
||||
- build_uwp
|
||||
- build_windows_xdp
|
||||
jobs:
|
||||
- template: .azure/obtemplates/build-nuget.yml@self
|
||||
${{ if startsWith(variables['Build.SourceBranch'], 'refs/tags/') }}:
|
||||
|
|
|
@ -82,22 +82,6 @@ extends:
|
|||
parameters:
|
||||
config: Debug
|
||||
|
||||
- stage: build_windows_xdp
|
||||
displayName: Build Windows XDP
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: .azure/obtemplates/build-winuser-xdp.yml@self
|
||||
parameters:
|
||||
config: Release
|
||||
tls: schannel
|
||||
- template: .azure/obtemplates/build-winuser-xdp.yml@self
|
||||
parameters:
|
||||
config: Release
|
||||
tls: openssl
|
||||
- template: .azure/obtemplates/build-winuser-xdp.yml@self
|
||||
parameters:
|
||||
config: Debug
|
||||
|
||||
- stage: build_windows
|
||||
displayName: Build Windows
|
||||
dependsOn: []
|
||||
|
@ -198,6 +182,5 @@ extends:
|
|||
dependsOn:
|
||||
- build_windows
|
||||
- build_uwp
|
||||
- build_windows_xdp
|
||||
jobs:
|
||||
- template: .azure/obtemplates/build-nuget.yml@self
|
||||
|
|
|
@ -157,7 +157,7 @@ stages:
|
|||
arch: ${{ parameters.arch }}
|
||||
config: Release
|
||||
|
||||
- ${{ if or(eq(parameters.winkernel, true), eq(parameters.winuser_schannel, true)) }}:
|
||||
- ${{ if or(eq(parameters.winkernel, true), eq(parameters.winuser_schannel, true), eq(parameters.winuser_xdp, true)) }}:
|
||||
- stage: build_winuser_schannel
|
||||
displayName: Build Windows (Schannel)
|
||||
dependsOn: []
|
||||
|
@ -171,33 +171,12 @@ stages:
|
|||
arch: ${{ parameters.arch }}
|
||||
tls: schannel
|
||||
config: Release
|
||||
extraPrepareArgs: -DisableTest
|
||||
extraPrepareArgs: -DisableTest -InstallXdpSdk
|
||||
${{ if eq(parameters.pgo_mode, false) }}:
|
||||
extraBuildArgs: -DisableTest -DisableTools
|
||||
${{ if eq(parameters.pgo_mode, true) }}:
|
||||
extraBuildArgs: -DisableTest -DisableTools -PGO
|
||||
|
||||
- ${{ if eq(parameters.winuser_xdp, true) }}:
|
||||
- stage: build_winuser_xdp
|
||||
displayName: Build Windows (XDP)
|
||||
dependsOn: []
|
||||
variables:
|
||||
runCodesignValidationInjection: false
|
||||
jobs:
|
||||
- template: ./templates/build-config-user.yml
|
||||
parameters:
|
||||
image: windows-latest
|
||||
platform: windows
|
||||
arch: ${{ parameters.arch }}
|
||||
tls: schannel
|
||||
config: Release
|
||||
extraName: 'xdp'
|
||||
extraPrepareArgs: -DisableTest -InstallXdpSdk
|
||||
${{ if eq(parameters.pgo_mode, false) }}:
|
||||
extraBuildArgs: -DisableTest -DisableTools -UseXdp -ExtraArtifactDir Xdp
|
||||
${{ if eq(parameters.pgo_mode, true) }}:
|
||||
extraBuildArgs: -DisableTest -DisableTools -UseXdp -ExtraArtifactDir Xdp -PGO
|
||||
|
||||
- ${{ if eq(parameters.winuser_openssl, true) }}:
|
||||
- stage: build_winuser_openssl
|
||||
displayName: Build Windows (OpenSSL)
|
||||
|
@ -331,7 +310,7 @@ stages:
|
|||
- stage: perf_winuser_xdp
|
||||
displayName: Performance Testing Windows (XDP)
|
||||
dependsOn:
|
||||
- build_winuser_xdp
|
||||
- build_winuser_schannel
|
||||
jobs:
|
||||
- template: ./templates/run-performance.yml
|
||||
parameters:
|
||||
|
@ -344,11 +323,10 @@ stages:
|
|||
protocol: ${{ parameters.protocol }}
|
||||
logProfile: ${{ parameters.logging }}
|
||||
timeout: ${{ parameters.timeout }}
|
||||
extraArtifactDir: '_Xdp'
|
||||
${{ if eq(parameters.QTIP, true) }}:
|
||||
extraTestArgs: -ExtraArtifactDir _Xdp -XDP -QTIP
|
||||
extraTestArgs: -XDP -QTIP
|
||||
${{ else }}:
|
||||
extraTestArgs: -ExtraArtifactDir _Xdp -XDP
|
||||
extraTestArgs: -XDP
|
||||
${{ if ne(parameters.testToRun, 'all') }}:
|
||||
testToRun: ${{ parameters.testToRun }}
|
||||
testTypes: Remote
|
||||
|
|
|
@ -34,7 +34,7 @@ stages:
|
|||
arch: x64
|
||||
tls: schannel
|
||||
config: Release
|
||||
extraPrepareArgs: -DisableTest
|
||||
extraPrepareArgs: -DisableTest -InstallXdpSdk
|
||||
extraBuildArgs: -DisableTest -DisableTools -PGO
|
||||
|
||||
- stage: build_winuser_openssl
|
||||
|
@ -69,23 +69,6 @@ stages:
|
|||
extraPrepareArgs: -DisableTest
|
||||
extraBuildArgs: -DisableTest -DisableTools -PGO
|
||||
|
||||
- stage: build_winuser_xdp
|
||||
displayName: Build Windows (XDP)
|
||||
dependsOn: []
|
||||
variables:
|
||||
runCodesignValidationInjection: false
|
||||
jobs:
|
||||
- template: ./templates/build-config-user.yml
|
||||
parameters:
|
||||
image: windows-latest
|
||||
platform: windows
|
||||
arch: x64
|
||||
tls: schannel
|
||||
config: Release
|
||||
extraName: 'xdp'
|
||||
extraPrepareArgs: -DisableTest -InstallXdpSdk
|
||||
extraBuildArgs: -DisableTest -DisableTools -UseXdp -ExtraArtifactDir Xdp -PGO
|
||||
|
||||
#
|
||||
# Performance Tests
|
||||
#
|
||||
|
@ -141,7 +124,7 @@ stages:
|
|||
- stage: perf_winuser_xdp
|
||||
displayName: Performance Testing Windows (XDP)
|
||||
dependsOn:
|
||||
- build_winuser_xdp
|
||||
- build_winuser_schannel
|
||||
jobs:
|
||||
- template: ./templates/run-performance.yml
|
||||
parameters:
|
||||
|
@ -150,8 +133,7 @@ stages:
|
|||
localTls: schannel
|
||||
remoteTls: schannel
|
||||
arch: x64
|
||||
extraArtifactDir: '_Xdp'
|
||||
extraTestArgs: -ExtraArtifactDir _Xdp -XDP
|
||||
extraTestArgs: -XDP
|
||||
testTypes: Remote
|
||||
extraArgs: -PGO
|
||||
failOnRegression: 0
|
||||
|
|
|
@ -56,19 +56,6 @@ jobs:
|
|||
artifact: drop_build_uwp_build_uwp_openssl_Debug
|
||||
path: $(Build.SourcesDirectory)\artifacts\bin\uwp
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
inputs:
|
||||
artifact: drop_build_windows_xdp_build_windows_schannel_Debug_xdp
|
||||
path: $(Build.SourcesDirectory)\artifacts\bin\windows
|
||||
- task: DownloadPipelineArtifact@2
|
||||
inputs:
|
||||
artifact: drop_build_windows_xdp_build_windows_schannel_Release_xdp
|
||||
path: $(Build.SourcesDirectory)\artifacts\bin\windows
|
||||
- task: DownloadPipelineArtifact@2
|
||||
inputs:
|
||||
artifact: drop_build_windows_xdp_build_windows_openssl_Release_xdp
|
||||
path: $(Build.SourcesDirectory)\artifacts\bin\windows
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Package Nuget
|
||||
inputs:
|
||||
|
@ -99,26 +86,6 @@ jobs:
|
|||
${{ if eq(parameters.release, true) }}:
|
||||
arguments: -Tls schannel -ReleaseBuild
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Package Nuget
|
||||
inputs:
|
||||
pwsh: false
|
||||
filePath: scripts/package-nuget.ps1
|
||||
${{ if eq(parameters.release, false) }}:
|
||||
arguments: -Tls schannel -XDP
|
||||
${{ if eq(parameters.release, true) }}:
|
||||
arguments: -Tls schannel -ReleaseBuild -XDP
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Package Nuget
|
||||
inputs:
|
||||
pwsh: false
|
||||
filePath: scripts/package-nuget.ps1
|
||||
${{ if eq(parameters.release, false) }}:
|
||||
arguments: -Tls openssl -XDP
|
||||
${{ if eq(parameters.release, true) }}:
|
||||
arguments: -Tls openssl -ReleaseBuild -XDP
|
||||
|
||||
- task: onebranch.pipeline.signing@1
|
||||
inputs:
|
||||
command: 'sign'
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
parameters:
|
||||
config: ''
|
||||
tls: 'schannel'
|
||||
platform: 'windows'
|
||||
|
||||
jobs:
|
||||
- job: build_${{ parameters.platform }}_${{ parameters.tls }}_${{ parameters.config }}_xdp
|
||||
displayName: ${{ parameters.platform }} ${{ parameters.tls }} ${{ parameters.config }} XDP
|
||||
pool:
|
||||
type: windows
|
||||
variables:
|
||||
ob_outputDirectory: $(Build.SourcesDirectory)\artifacts\bin\${{ parameters.platform }}
|
||||
ob_sdl_binskim_break: true # https://aka.ms/obpipelines/sdl
|
||||
ob_sdl_codeSignValidation_excludes: -|**\*.exe # Disable signing requirements for test executables
|
||||
steps:
|
||||
- task: PowerShell@2
|
||||
displayName: Prepare Build Machine
|
||||
target: windows_build_container2
|
||||
inputs:
|
||||
pwsh: true
|
||||
filePath: scripts/prepare-machine.ps1
|
||||
arguments: -InstallXdpSdk -ForContainerBuild
|
||||
- task: PowerShell@2
|
||||
displayName: x64
|
||||
target: windows_build_container2
|
||||
inputs:
|
||||
pwsh: true
|
||||
filePath: scripts/build.ps1
|
||||
arguments: -Tls ${{ parameters.tls }} -Config ${{ parameters.config }} -Platform ${{ parameters.platform }} -Arch x64 -CI -UseXdp -ExtraArtifactDir xdp -OfficialRelease
|
||||
- task: onebranch.pipeline.signing@1
|
||||
target: windows_build_container2
|
||||
inputs:
|
||||
command: 'sign'
|
||||
signing_profile: 'external_distribution'
|
||||
files_to_sign: '**/*.dll'
|
||||
search_root: '$(ob_outputDirectory)'
|
|
@ -13,6 +13,13 @@ jobs:
|
|||
ob_sdl_binskim_break: true # https://aka.ms/obpipelines/sdl
|
||||
ob_sdl_codeSignValidation_excludes: -|**\*.exe # Disable signing requirements for test executables
|
||||
steps:
|
||||
- task: PowerShell@2
|
||||
displayName: Prepare Build Machine
|
||||
target: windows_build_container2
|
||||
inputs:
|
||||
pwsh: true
|
||||
filePath: scripts/prepare-machine.ps1
|
||||
arguments: -InstallXdpSdk -ForContainerBuild
|
||||
- task: PowerShell@2
|
||||
displayName: x64
|
||||
target: windows_build_container2
|
||||
|
|
|
@ -47,10 +47,6 @@ on:
|
|||
# - openssl
|
||||
# - openssl3
|
||||
# - schannel
|
||||
xdp:
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
static:
|
||||
required: false
|
||||
default: ''
|
||||
|
@ -89,11 +85,11 @@ jobs:
|
|||
- name: Build For Test
|
||||
if: inputs.test == '-Test'
|
||||
shell: pwsh
|
||||
run: scripts/build.ps1 -Config ${{ inputs.config }} -Platform ${{ inputs.plat }} -Arch ${{ inputs.arch }} -Tls ${{ inputs.tls }} -DisablePerf -DynamicCRT ${{ inputs.xdp }} ${{ inputs.sanitize }}
|
||||
run: scripts/build.ps1 -Config ${{ inputs.config }} -Platform ${{ inputs.plat }} -Arch ${{ inputs.arch }} -Tls ${{ inputs.tls }} -DisablePerf -DynamicCRT ${{ inputs.sanitize }}
|
||||
- name: Build
|
||||
if: inputs.test == ''
|
||||
shell: pwsh
|
||||
run: scripts/build.ps1 -Config ${{ inputs.config }} -Platform ${{ inputs.plat }} -Arch ${{ inputs.arch }} -Tls ${{ inputs.tls }} ${{ inputs.xdp }} ${{ inputs.sanitize }} ${{ inputs.static }}
|
||||
run: scripts/build.ps1 -Config ${{ inputs.config }} -Platform ${{ inputs.plat }} -Arch ${{ inputs.arch }} -Tls ${{ inputs.tls }} ${{ inputs.sanitize }} ${{ inputs.static }}
|
||||
- name: Filter Build Artifacts
|
||||
shell: pwsh
|
||||
run: |
|
||||
|
@ -103,5 +99,5 @@ jobs:
|
|||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32
|
||||
with:
|
||||
name: ${{ inputs.config }}-${{ inputs.plat }}-${{ inputs.os }}-${{ inputs.arch }}-${{ inputs.tls }}${{ inputs.xdp }}${{ inputs.sanitize }}${{ inputs.static }}${{ inputs.test }}
|
||||
name: ${{ inputs.config }}-${{ inputs.plat }}-${{ inputs.os }}-${{ inputs.arch }}-${{ inputs.tls }}${{ inputs.sanitize }}${{ inputs.static }}${{ inputs.test }}
|
||||
path: artifacts
|
||||
|
|
|
@ -32,7 +32,6 @@ jobs:
|
|||
arch: [x86, x64, arm64]
|
||||
tls: [schannel, openssl, openssl3]
|
||||
static: ['', '-Static']
|
||||
xdp: ['', '-UseXdp']
|
||||
exclude:
|
||||
# OpenSSL doesn't support arm64
|
||||
- tls: openssl
|
||||
|
@ -46,15 +45,6 @@ jobs:
|
|||
# TODO: FIX: Static builds fail with UWP
|
||||
- plat: uwp
|
||||
static: '-Static'
|
||||
# XDP not supported in UWP
|
||||
- plat: uwp
|
||||
xdp: '-UseXdp'
|
||||
# XDP only supports x64 currently
|
||||
- arch: x86
|
||||
xdp: '-UseXdp'
|
||||
# XDP only supports x64 currently
|
||||
- arch: arm64
|
||||
xdp: '-UseXdp'
|
||||
uses: ./.github/workflows/build-reuse-win.yml
|
||||
with:
|
||||
config: ${{ matrix.config }}
|
||||
|
@ -63,7 +53,6 @@ jobs:
|
|||
arch: ${{ matrix.arch }}
|
||||
tls: ${{ matrix.tls }}
|
||||
static: ${{ matrix.static }}
|
||||
xdp: ${{ matrix.xdp }}
|
||||
|
||||
build-windows-kernel:
|
||||
name: WinKernel
|
||||
|
@ -201,8 +190,6 @@ jobs:
|
|||
{ plat: "uwp", tls: "openssl", arg: "-UWP" },
|
||||
{ plat: "windows", tls: "openssl" },
|
||||
{ plat: "windows", tls: "schannel" },
|
||||
{ plat: "windows", tls: "openssl", xdp: "-UseXdp", arg: "-XDP" },
|
||||
{ plat: "windows", tls: "schannel", xdp: "-UseXdp", arg: "-XDP" },
|
||||
]
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
|
@ -211,19 +198,19 @@ jobs:
|
|||
- name: Download Build Artifacts
|
||||
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615
|
||||
with:
|
||||
name: Release-${{ matrix.vec.plat }}-windows-2022-x86-${{ matrix.vec.tls }}${{ matrix.vec.xdp }}
|
||||
name: Release-${{ matrix.vec.plat }}-windows-2022-x86-${{ matrix.vec.tls }}
|
||||
path: artifacts
|
||||
if_no_artifact_found: ignore
|
||||
- name: Download Build Artifacts
|
||||
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615
|
||||
with:
|
||||
name: Release-${{ matrix.vec.plat }}-windows-2022-x64-${{ matrix.vec.tls }}${{ matrix.vec.xdp }}
|
||||
name: Release-${{ matrix.vec.plat }}-windows-2022-x64-${{ matrix.vec.tls }}
|
||||
path: artifacts
|
||||
if_no_artifact_found: ignore
|
||||
- name: Download Build Artifacts
|
||||
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615
|
||||
with:
|
||||
name: Release-${{ matrix.vec.plat }}-windows-2022-arm64-${{ matrix.vec.tls }}${{ matrix.vec.xdp }}
|
||||
name: Release-${{ matrix.vec.plat }}-windows-2022-arm64-${{ matrix.vec.tls }}
|
||||
path: artifacts
|
||||
if_no_artifact_found: ignore
|
||||
- name: Build Package
|
||||
|
@ -232,5 +219,5 @@ jobs:
|
|||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32
|
||||
with:
|
||||
name: Nuget-Release-${{ matrix.vec.plat }}-windows-2022-arm64-${{ matrix.vec.tls }}${{ matrix.vec.xdp }}
|
||||
name: Nuget-Release-${{ matrix.vec.plat }}-windows-2022-arm64-${{ matrix.vec.tls }}
|
||||
path: artifacts/dist/*.nupkg
|
||||
|
|
|
@ -45,4 +45,4 @@ jobs:
|
|||
- name: Cargo test
|
||||
run: cargo test --all
|
||||
- name: Cargo Publish (dry run)
|
||||
run: cargo publish --dry-run
|
||||
run: cargo publish --dry-run --allow-dirty
|
||||
|
|
|
@ -35,7 +35,6 @@ jobs:
|
|||
os: ${{ matrix.vec.os }}
|
||||
arch: ${{ matrix.vec.arch }}
|
||||
tls: ${{ matrix.vec.tls }}
|
||||
xdp: ${{ matrix.vec.xdp }}
|
||||
sanitize: ${{ matrix.vec.sanitize }}
|
||||
test: ${{ matrix.vec.test }}
|
||||
|
||||
|
@ -59,10 +58,10 @@ jobs:
|
|||
- name: Download Build Artifacts
|
||||
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
|
||||
with:
|
||||
name: ${{ matrix.vec.config }}-${{ matrix.vec.plat }}-${{ matrix.vec.os }}-${{ matrix.vec.arch }}-${{ matrix.vec.tls }}${{ matrix.vec.xdp }}${{ matrix.vec.sanitize }}${{ matrix.vec.test }}
|
||||
name: ${{ matrix.vec.config }}-${{ matrix.vec.plat }}-${{ matrix.vec.os }}-${{ matrix.vec.arch }}-${{ matrix.vec.tls }}${{ matrix.vec.sanitize }}${{ matrix.vec.test }}
|
||||
path: artifacts
|
||||
- name: Prepare Machine
|
||||
run: scripts/prepare-machine.ps1 -Tls ${{ matrix.vec.tls }} -ForTest ${{ matrix.vec.xdp }} -InstallCodeCoverage
|
||||
run: scripts/prepare-machine.ps1 -Tls ${{ matrix.vec.tls }} -ForTest -InstallCodeCoverage
|
||||
shell: pwsh
|
||||
- name: Install ETW Manifest
|
||||
shell: pwsh
|
||||
|
@ -79,7 +78,7 @@ jobs:
|
|||
- name: Upload Results
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32
|
||||
with:
|
||||
name: BVT-${{ matrix.vec.config }}-${{ matrix.vec.plat }}-${{ matrix.vec.os }}-${{ matrix.vec.arch }}-${{ matrix.vec.tls }}${{ matrix.vec.xdp }}${{ matrix.vec.qtip }}${{ matrix.vec.systemcrypto }}${{ matrix.vec.sanitize }}
|
||||
name: BVT-${{ matrix.vec.config }}-${{ matrix.vec.plat }}-${{ matrix.vec.os }}-${{ matrix.vec.arch }}-${{ matrix.vec.tls }}${{ matrix.vec.qtip }}${{ matrix.vec.systemcrypto }}${{ matrix.vec.sanitize }}
|
||||
path: artifacts/coverage/*.cov
|
||||
|
||||
stress-winlatest:
|
||||
|
@ -109,7 +108,7 @@ jobs:
|
|||
fetch-depth: 0
|
||||
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
|
||||
with:
|
||||
name: ${{ matrix.vec.config }}-${{ matrix.vec.plat }}-${{ matrix.vec.os }}-${{ matrix.vec.arch }}-${{ matrix.vec.tls }}${{ matrix.vec.xdp }}${{ matrix.vec.sanitize }}${{ matrix.vec.test }}
|
||||
name: ${{ matrix.vec.config }}-${{ matrix.vec.plat }}-${{ matrix.vec.os }}-${{ matrix.vec.arch }}-${{ matrix.vec.tls }}${{ matrix.vec.sanitize }}${{ matrix.vec.test }}
|
||||
path: artifacts
|
||||
- name: Prepare Machine
|
||||
run: scripts/prepare-machine.ps1 -Tls ${{ matrix.vec.tls }} -ForTest ${{ matrix.vec.xdp }} -InstallCodeCoverage
|
||||
|
|
|
@ -28,15 +28,10 @@ jobs:
|
|||
vec: [
|
||||
{ config: "Debug", plat: "windows", os: "windows-2019", arch: "x64", tls: "openssl", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2019", arch: "x64", tls: "openssl3", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2019", arch: "x64", tls: "openssl", xdp: "-UseXdp", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2019", arch: "x64", tls: "openssl3", xdp: "-UseXdp", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "schannel", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "schannel", sanitize: "-Sanitize", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "schannel", xdp: "-UseXdp", sanitize: "-Sanitize", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "openssl", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "openssl", xdp: "-UseXdp", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "openssl3", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "openssl3", xdp: "-UseXdp", test: "-Test" }
|
||||
]
|
||||
uses: ./.github/workflows/build-reuse-win.yml
|
||||
with:
|
||||
|
@ -45,7 +40,6 @@ jobs:
|
|||
os: ${{ matrix.vec.os }}
|
||||
arch: ${{ matrix.vec.arch }}
|
||||
tls: ${{ matrix.vec.tls }}
|
||||
xdp: ${{ matrix.vec.xdp }}
|
||||
sanitize: ${{ matrix.vec.sanitize }}
|
||||
test: ${{ matrix.vec.test }}
|
||||
|
||||
|
@ -108,7 +102,7 @@ jobs:
|
|||
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
|
||||
if: matrix.vec.plat == 'windows'
|
||||
with:
|
||||
name: ${{ matrix.vec.config }}-${{ matrix.vec.plat }}-${{ matrix.vec.os == 'WSPrerelease' && 'windows-2022' || matrix.vec.os }}-${{ matrix.vec.arch }}-${{ matrix.vec.tls }}${{ matrix.vec.xdp }}${{ matrix.vec.sanitize }}${{ matrix.vec.test }}
|
||||
name: ${{ matrix.vec.config }}-${{ matrix.vec.plat }}-${{ matrix.vec.os == 'WSPrerelease' && 'windows-2022' || matrix.vec.os }}-${{ matrix.vec.arch }}-${{ matrix.vec.tls }}${{ matrix.vec.sanitize }}${{ matrix.vec.test }}
|
||||
path: artifacts
|
||||
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
|
||||
if: matrix.vec.plat == 'linux' || matrix.vec.plat == 'macos'
|
||||
|
|
|
@ -46,15 +46,10 @@ jobs:
|
|||
vec: [
|
||||
{ config: "Debug", plat: "windows", os: "windows-2019", arch: "x64", tls: "openssl", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2019", arch: "x64", tls: "openssl3", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2019", arch: "x64", tls: "openssl", xdp: "-UseXdp", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2019", arch: "x64", tls: "openssl3", xdp: "-UseXdp", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "schannel", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "schannel", sanitize: "-Sanitize", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "schannel", xdp: "-UseXdp", sanitize: "-Sanitize", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "openssl", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "openssl", xdp: "-UseXdp", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "openssl3", test: "-Test" },
|
||||
{ config: "Debug", plat: "windows", os: "windows-2022", arch: "x64", tls: "openssl3", xdp: "-UseXdp", test: "-Test" },
|
||||
{ config: "Release", plat: "windows", os: "windows-2022", arch: "x64", tls: "schannel", test: "-Test" }
|
||||
]
|
||||
uses: ./.github/workflows/build-reuse-win.yml
|
||||
|
@ -64,7 +59,6 @@ jobs:
|
|||
os: ${{ matrix.vec.os }}
|
||||
arch: ${{ matrix.vec.arch }}
|
||||
tls: ${{ matrix.vec.tls }}
|
||||
xdp: ${{ matrix.vec.xdp }}
|
||||
sanitize: ${{ matrix.vec.sanitize }}
|
||||
test: ${{ matrix.vec.test }}
|
||||
|
||||
|
@ -127,7 +121,7 @@ jobs:
|
|||
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
|
||||
if: matrix.vec.plat == 'windows'
|
||||
with: # note that BVT for WSPrerelease uses binaries built on windows-2022.
|
||||
name: ${{ matrix.vec.config }}-${{ matrix.vec.plat }}-${{ matrix.vec.os == 'WSPrerelease' && 'windows-2022' || matrix.vec.os }}-${{ matrix.vec.arch }}-${{ matrix.vec.tls }}${{ matrix.vec.xdp }}${{ matrix.vec.sanitize }}${{ matrix.vec.test }}
|
||||
name: ${{ matrix.vec.config }}-${{ matrix.vec.plat }}-${{ matrix.vec.os == 'WSPrerelease' && 'windows-2022' || matrix.vec.os }}-${{ matrix.vec.arch }}-${{ matrix.vec.tls }}${{ matrix.vec.sanitize }}${{ matrix.vec.test }}
|
||||
path: artifacts
|
||||
- name: Download Build Artifacts
|
||||
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
|
||||
|
@ -234,7 +228,7 @@ jobs:
|
|||
fetch-depth: 0
|
||||
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
|
||||
with:
|
||||
name: ${{ matrix.vec.config }}-${{ matrix.vec.plat }}-${{ matrix.vec.os }}-${{ matrix.vec.arch }}-${{ matrix.vec.tls }}${{ matrix.vec.xdp }}${{ matrix.vec.sanitize }}${{ matrix.vec.test }}
|
||||
name: ${{ matrix.vec.config }}-${{ matrix.vec.plat }}-${{ matrix.vec.os }}-${{ matrix.vec.arch }}-${{ matrix.vec.tls }}${{ matrix.vec.sanitize }}${{ matrix.vec.test }}
|
||||
path: artifacts
|
||||
- name: Prepare Machine
|
||||
run: scripts/prepare-machine.ps1 -ForTest ${{ matrix.vec.xdp }}
|
||||
|
|
|
@ -100,7 +100,6 @@ option(QUIC_SKIP_CI_CHECKS "Disable CI specific build checks" OFF)
|
|||
option(QUIC_TELEMETRY_ASSERTS "Enable telemetry asserts in release builds" OFF)
|
||||
option(QUIC_USE_SYSTEM_LIBCRYPTO "Use system libcrypto if openssl TLS" OFF)
|
||||
option(QUIC_HIGH_RES_TIMERS "Configure the system to use high resolution timers" OFF)
|
||||
option(QUIC_USE_XDP "Uses XDP instead of socket APIs" OFF)
|
||||
option(QUIC_OFFICIAL_RELEASE "Configured the build for an official release" OFF)
|
||||
set(QUIC_FOLDER_PREFIX "" CACHE STRING "Optional prefix for source group folders when using an IDE generator")
|
||||
set(QUIC_LIBRARY_NAME "msquic" CACHE STRING "Override the output library name")
|
||||
|
@ -555,11 +554,6 @@ if(WIN32)
|
|||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG /IGNORE:4075 /DEBUG /OPT:REF /OPT:ICF")
|
||||
|
||||
# Find the right PGO file.
|
||||
if(QUIC_USE_XDP)
|
||||
set(QUIC_PGO_NAME "msquic.${QUIC_TLS}.xdp.pgd")
|
||||
set(QUIC_PGO_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/bin/winuser/pgo_${SYSTEM_PROCESSOR}/${QUIC_PGO_NAME}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${QUIC_PGO_FILE}")
|
||||
set(QUIC_PGO_NAME "msquic.${QUIC_TLS}.pgd")
|
||||
set(QUIC_PGO_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/bin/winuser/pgo_${SYSTEM_PROCESSOR}/${QUIC_PGO_NAME}")
|
||||
|
|
|
@ -40,6 +40,7 @@ include = [
|
|||
"/src/generated",
|
||||
"/src/manifest",
|
||||
"/src/platform",
|
||||
"/artifacts/xdp/include",
|
||||
"/THIRD-PARTY-NOTICES",
|
||||
]
|
||||
|
||||
|
|
|
@ -26,7 +26,12 @@ Another large piece of the PAL is the abstraction of UDP and TCP sockets, named
|
|||
|
||||
It uses asynchronous callbacks driven by the current execution model (see [below](#execution-model)) threads.
|
||||
|
||||
Currently, it also has preview support of XDP on Windows.
|
||||
Currently, it also has preview support of XDP on Windows.
|
||||
XDP datapath is used when
|
||||
- XDP initialization succeeds
|
||||
- XDP deps are installed
|
||||
- XDP capable NIC is available
|
||||
- Targetting to non-loopback address
|
||||
|
||||
### Crypto
|
||||
|
||||
|
|
|
@ -23,6 +23,11 @@ Then all the tests can be run with:
|
|||
./scripts/test.ps1 -Tls openssl
|
||||
```
|
||||
|
||||
Windows XDP datapath can be used unless a test explicitly specify loopback address by
|
||||
```Powershell
|
||||
./scripts/test.ps1 -UseXdp
|
||||
```
|
||||
|
||||
By default this will run all tests in series, with no log collection. To include log collection for failed tests, run:
|
||||
|
||||
```PowerShell
|
||||
|
|
|
@ -90,9 +90,6 @@ This script provides helpers for building msquic.
|
|||
.PARAMETER EnableHighResolutionTimers
|
||||
Configures the system to use high resolution timers.
|
||||
|
||||
.PARAMETER UseXdp
|
||||
Use XDP for the datapath instead of system socket APIs.
|
||||
|
||||
.PARAMETER ExtraArtifactDir
|
||||
Add an extra classifier to the artifact directory to allow publishing alternate builds of same base library
|
||||
|
||||
|
@ -202,9 +199,6 @@ param (
|
|||
[Parameter(Mandatory = $false)]
|
||||
[switch]$EnableHighResolutionTimers = $false,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$UseXdp = $false,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[string]$ExtraArtifactDir = "",
|
||||
|
||||
|
@ -487,9 +481,6 @@ function CMake-Generate {
|
|||
if ($EnableHighResolutionTimers) {
|
||||
$Arguments += " -DQUIC_HIGH_RES_TIMERS=on"
|
||||
}
|
||||
if ($UseXdp) {
|
||||
$Arguments += " -DQUIC_USE_XDP=on"
|
||||
}
|
||||
if ($Platform -eq "android") {
|
||||
$env:PATH = "$env:ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$env:PATH"
|
||||
switch ($Arch) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
../src/platform/certificates_posix.c
|
||||
../src/platform/hashtable.c
|
||||
../src/platform/datapath_winuser.c
|
||||
../src/platform/datapath_linux.c
|
||||
../src/platform/datapath_raw_dpdk.c
|
||||
../src/platform/datapath_raw_socket.c
|
||||
../src/platform/datapath_raw_socket_win.c
|
||||
|
|
|
@ -43,7 +43,6 @@ git checkout -b $BranchName
|
|||
Copy-Item -Path artifacts/PerfDataResults/performance/windows/$($Arch)_$($Config)_schannel/msquic.pgd src/bin/winuser/pgo_$($Arch)/msquic.schannel.pgd -Force
|
||||
Copy-Item -Path artifacts/PerfDataResults/performance/windows/$($Arch)_$($Config)_openssl/msquic.pgd src/bin/winuser/pgo_$($Arch)/msquic.openssl.pgd -Force
|
||||
Copy-Item -Path artifacts/PerfDataResults/performance/windows/$($Arch)_$($Config)_openssl3/msquic.pgd src/bin/winuser/pgo_$($Arch)/msquic.openssl3.pgd -Force
|
||||
Copy-Item -Path artifacts/PerfDataResults/performance/windows/$($Arch)_$($Config)_schannel_Xdp/msquic.pgd src/bin/winuser/pgo_$($Arch)/msquic.schannel.xdp.pgd -Force
|
||||
|
||||
# Commit the new PGD files.
|
||||
git commit -am "Update PGO data"
|
||||
|
|
|
@ -22,9 +22,6 @@ param (
|
|||
[Parameter(Mandatory = $false)]
|
||||
[switch]$UWP = $false,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$XDP = $false,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$ReleaseBuild = $false,
|
||||
|
||||
|
@ -87,10 +84,7 @@ if ((Test-Path $PackagingDir)) {
|
|||
# Arm is ignored, as there are no shipping arm devices
|
||||
$Architectures = "x64","x86","arm64"
|
||||
|
||||
if ($XDP) {
|
||||
# XDP only supports x64
|
||||
$Architectures = "x64"
|
||||
} elseif ($Tls -ne "schannel") {
|
||||
if ($Tls -ne "schannel") {
|
||||
# OpenSSL doesn't support arm64 currently
|
||||
$Architectures = "x64","x86"
|
||||
}
|
||||
|
@ -100,9 +94,6 @@ $NativeDir = Join-Path $PackagingDir "build/native"
|
|||
|
||||
foreach ($Arch in $Architectures) {
|
||||
$BuildPath = Join-Path $PlatformDir "$($Arch)_$($Config)_$($Tls)"
|
||||
if ($XDP -and !$GHA) {
|
||||
$BuildPath += "_xdp"
|
||||
}
|
||||
$LibPath = Join-Path $NativeDir "lib/$Arch"
|
||||
$BinPath = Join-Path $NativeDir "bin/$Arch"
|
||||
|
||||
|
@ -144,10 +135,8 @@ $NugetSourceFolder = Join-Path $RootDir "src/distribution"
|
|||
|
||||
if ($UWP) {
|
||||
$PackageName = "Microsoft.Native.Quic.MsQuic.UWP.$Tls"
|
||||
} elseif ($XDP) {
|
||||
Copy-Item -Path (Join-Path $PSScriptRoot xdp.json) -Destination (Join-Path $PackagingDir xdp-temp.json)
|
||||
$PackageName = "Microsoft.Native.Quic.MsQuic.XDP.$Tls"
|
||||
} else {
|
||||
Copy-Item -Path (Join-Path $PSScriptRoot xdp.json) -Destination $PackagingDir
|
||||
$PackageName = "Microsoft.Native.Quic.MsQuic.$Tls"
|
||||
}
|
||||
|
||||
|
|
|
@ -362,8 +362,8 @@ function LocalTeardown {
|
|||
}
|
||||
}
|
||||
|
||||
$RemoteExePath = Get-ExePath -PathRoot $RemoteDirectory -Platform $RemotePlatform -IsRemote $true -ExtraArtifactDir $ExtraArtifactDir
|
||||
$LocalExePath = Get-ExePath -PathRoot $LocalDirectory -Platform $LocalPlatform -IsRemote $false -ExtraArtifactDir $ExtraArtifactDir
|
||||
$RemoteExePath = Get-ExePath -PathRoot $RemoteDirectory -Platform $RemotePlatform -IsRemote $true
|
||||
$LocalExePath = Get-ExePath -PathRoot $LocalDirectory -Platform $LocalPlatform -IsRemote $false
|
||||
|
||||
# See if we are an AZP PR
|
||||
$PrBranchName = $env:SYSTEM_PULLREQUEST_TARGETBRANCH
|
||||
|
@ -399,8 +399,8 @@ function Invoke-Test {
|
|||
|
||||
Write-Output "Running Test $Test"
|
||||
|
||||
$RemoteExe = Get-ExeName -PathRoot $RemoteDirectory -Platform $RemotePlatform -IsRemote $true -TestPlat $RemoteConfig -ExtraArtifactDir $ExtraArtifactDir
|
||||
$LocalExe = Get-ExeName -PathRoot $LocalDirectory -Platform $LocalPlatform -IsRemote $false -TestPlat $Test.Local -ExtraArtifactDir $ExtraArtifactDir
|
||||
$RemoteExe = Get-ExeName -PathRoot $RemoteDirectory -Platform $RemotePlatform -IsRemote $true -TestPlat $RemoteConfig
|
||||
$LocalExe = Get-ExeName -PathRoot $LocalDirectory -Platform $LocalPlatform -IsRemote $false -TestPlat $Test.Local
|
||||
|
||||
# Check both Exes
|
||||
$RemoteExeExists = Invoke-TestCommand -Session $Session -ScriptBlock {
|
||||
|
|
|
@ -109,17 +109,6 @@ if ($PSVersionTable.PSVersion.Major -lt 7) {
|
|||
"Please visit https://github.com/microsoft/msquic/blob/main/docs/BUILD.md#powershell-usage")
|
||||
}
|
||||
|
||||
if ($UseXdp) {
|
||||
# Helper for XDP usage
|
||||
if ($ForBuild) {
|
||||
$InstallXdpSdk = $true;
|
||||
}
|
||||
if ($ForTest) {
|
||||
$InstallXdpDriver = $true;
|
||||
$InstallDuoNic = $true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$ForContainerBuild -and !$ForBuild -and !$ForTest -and !$InstallXdpDriver -and !$UninstallXdp) {
|
||||
# When no args are passed, assume we want to build and test everything
|
||||
# locally (i.e. a dev environment). Set Tls to OpenSSL to make sure
|
||||
|
@ -151,6 +140,11 @@ if ($ForTest) {
|
|||
$InstallSigningCertificates = $true;
|
||||
}
|
||||
|
||||
if ($UseXdp) {
|
||||
$InstallXdpDriver = $true;
|
||||
$InstallDuoNic = $true;
|
||||
}
|
||||
|
||||
#$InstallCodeCoverage = $true # Ideally we'd enable this by default, but it
|
||||
# hangs sometimes, so we only want to install
|
||||
# for jobs that absoultely need it.
|
||||
|
|
Двоичные данные
src/bin/winuser/pgo_x64/msquic.schannel.xdp.pgd
Двоичные данные
src/bin/winuser/pgo_x64/msquic.schannel.xdp.pgd
Двоичный файл не отображается.
|
@ -720,7 +720,7 @@ QuicPacketBuilderFinalize(
|
|||
|
||||
FinalQuicPacket = TRUE;
|
||||
|
||||
if (!FlushBatchedDatagrams && CxPlatDataPathIsPaddingPreferred(MsQuicLib.Datapath)) {
|
||||
if (!FlushBatchedDatagrams && CxPlatDataPathIsPaddingPreferred(MsQuicLib.Datapath, Builder->SendData)) {
|
||||
//
|
||||
// When buffering multiple datagrams in a single contiguous buffer
|
||||
// (at the datapath layer), all but the last datagram needs to be
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Microsoft.Native.Quic.MsQuic.XDP.OpenSSL</id>
|
||||
<version>0.0.0</version>
|
||||
<title>MsQuic XDP (OpenSSL)</title>
|
||||
<authors>Microsoft</authors>
|
||||
<license type="expression">MIT</license>
|
||||
<icon>pkgicon.png</icon>
|
||||
<readme>README.md</readme>
|
||||
<projectUrl>https://github.com/microsoft/msquic</projectUrl>
|
||||
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
|
||||
<description>MsQuic native library for x64, x86 and arm64 using openssl for TLS and XDP datapath</description>
|
||||
<repository type="git" url="$RepoRemote$" commit="$CommitHash$" />
|
||||
<tags>native quic msquic openssl xdp</tags>
|
||||
</metadata>
|
||||
</package>
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link Condition="'$(Platform.ToLower())' == 'x64'">
|
||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib/x64/msquic.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<!-- <Link Condition="'$(Platform.ToLower())' == 'arm64'">
|
||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib/arm64/msquic.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link> -->
|
||||
</ItemDefinitionGroup>
|
||||
<Target Name="msquic_AfterBuild" AfterTargets="AfterBuild" />
|
||||
<Target Name="msquic_AfterBuild_x64" Label="x64" Condition="'$(Platform.ToLower())' == 'x64'" AfterTargets="msquic_AfterBuild">
|
||||
<Copy SourceFiles="$(MSBuildThisFileDirectory)bin/x64/msquic.dll" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
<!-- <Target Name="msquic_AfterBuild_arm64" Label="arm64" Condition="'$(Platform.ToLower())' == 'arm64'" AfterTargets="msquic_AfterBuild">
|
||||
<Copy SourceFiles="$(MSBuildThisFileDirectory)bin/arm64/msquic.dll" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" />
|
||||
</Target> -->
|
||||
</Project>
|
|
@ -1,18 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Microsoft.Native.Quic.MsQuic.XDP.Schannel</id>
|
||||
<version>0.0.0</version>
|
||||
<title>MsQuic XDP (Schannel)</title>
|
||||
<authors>Microsoft</authors>
|
||||
<license type="expression">MIT</license>
|
||||
<icon>pkgicon.png</icon>
|
||||
<readme>README.md</readme>
|
||||
<projectUrl>https://github.com/microsoft/msquic</projectUrl>
|
||||
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
|
||||
<description>MsQuic native library for x64, x86 and arm64 using schannel for TLS and XDP datapath</description>
|
||||
<repository type="git" url="$RepoRemote$" commit="$CommitHash$" />
|
||||
<tags>native quic msquic schannel xdp</tags>
|
||||
</metadata>
|
||||
</package>
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link Condition="'$(Platform.ToLower())' == 'x64'">
|
||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib/x64/msquic.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<!-- <Link Condition="'$(Platform.ToLower())' == 'arm64'">
|
||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib/arm64/msquic.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link> -->
|
||||
</ItemDefinitionGroup>
|
||||
<Target Name="msquic_AfterBuild" AfterTargets="AfterBuild" />
|
||||
<Target Name="msquic_AfterBuild_x64" Label="x64" Condition="'$(Platform.ToLower())' == 'x64'" AfterTargets="msquic_AfterBuild">
|
||||
<Copy SourceFiles="$(MSBuildThisFileDirectory)bin/x64/msquic.dll" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
<!-- <Target Name="msquic_AfterBuild_arm64" Label="arm64" Condition="'$(Platform.ToLower())' == 'arm64'" AfterTargets="msquic_AfterBuild">
|
||||
<Copy SourceFiles="$(MSBuildThisFileDirectory)bin/arm64/msquic.dll" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" />
|
||||
</Target> -->
|
||||
</Project>
|
|
@ -18,10 +18,6 @@
|
|||
#define _clog_MACRO_QuicTraceLogWarning 1
|
||||
#define QuicTraceLogWarning(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
|
||||
#endif
|
||||
#ifndef _clog_MACRO_QuicTraceLogError
|
||||
#define _clog_MACRO_QuicTraceLogError 1
|
||||
#define QuicTraceLogError(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
|
||||
#endif
|
||||
#ifndef _clog_MACRO_QuicTraceEvent
|
||||
#define _clog_MACRO_QuicTraceEvent 1
|
||||
#define QuicTraceEvent(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
|
||||
|
@ -47,26 +43,6 @@ tracepoint(CLOG_DATAPATH_EPOLL_C, DatapathRecvEmpty , arg2);\
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathResolveHostNameFailed
|
||||
// [%p] Couldn't resolve hostname '%s' to an IP address
|
||||
// QuicTraceLogError(
|
||||
DatapathResolveHostNameFailed,
|
||||
"[%p] Couldn't resolve hostname '%s' to an IP address",
|
||||
Datapath,
|
||||
HostName);
|
||||
// arg2 = arg2 = Datapath = arg2
|
||||
// arg3 = arg3 = HostName = arg3
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_4_ARGS_TRACE_DatapathResolveHostNameFailed
|
||||
#define _clog_4_ARGS_TRACE_DatapathResolveHostNameFailed(uniqueId, encoded_arg_string, arg2, arg3)\
|
||||
tracepoint(CLOG_DATAPATH_EPOLL_C, DatapathResolveHostNameFailed , arg2, arg3);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for AllocFailure
|
||||
// Allocation of '%s' failed. (%llu bytes)
|
||||
|
@ -87,26 +63,6 @@ tracepoint(CLOG_DATAPATH_EPOLL_C, AllocFailure , arg2, arg3);\
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for LibraryErrorStatus
|
||||
// [ lib] ERROR, %u, %s.
|
||||
// QuicTraceEvent(
|
||||
LibraryErrorStatus,
|
||||
"[ lib] ERROR, %u, %s.",
|
||||
(uint32_t)Result,
|
||||
"Resolving hostname to IP");
|
||||
// arg2 = arg2 = (uint32_t)Result = arg2
|
||||
// arg3 = arg3 = "Resolving hostname to IP" = arg3
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_4_ARGS_TRACE_LibraryErrorStatus
|
||||
#define _clog_4_ARGS_TRACE_LibraryErrorStatus(uniqueId, encoded_arg_string, arg2, arg3)\
|
||||
tracepoint(CLOG_DATAPATH_EPOLL_C, LibraryErrorStatus , arg2, arg3);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathErrorStatus
|
||||
// [data][%p] ERROR, %u, %s.
|
||||
|
|
|
@ -20,29 +20,6 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_EPOLL_C, DatapathRecvEmpty,
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathResolveHostNameFailed
|
||||
// [%p] Couldn't resolve hostname '%s' to an IP address
|
||||
// QuicTraceLogError(
|
||||
DatapathResolveHostNameFailed,
|
||||
"[%p] Couldn't resolve hostname '%s' to an IP address",
|
||||
Datapath,
|
||||
HostName);
|
||||
// arg2 = arg2 = Datapath = arg2
|
||||
// arg3 = arg3 = HostName = arg3
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_DATAPATH_EPOLL_C, DatapathResolveHostNameFailed,
|
||||
TP_ARGS(
|
||||
const void *, arg2,
|
||||
const char *, arg3),
|
||||
TP_FIELDS(
|
||||
ctf_integer_hex(uint64_t, arg2, arg2)
|
||||
ctf_string(arg3, arg3)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for AllocFailure
|
||||
// Allocation of '%s' failed. (%llu bytes)
|
||||
|
@ -66,29 +43,6 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_EPOLL_C, AllocFailure,
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for LibraryErrorStatus
|
||||
// [ lib] ERROR, %u, %s.
|
||||
// QuicTraceEvent(
|
||||
LibraryErrorStatus,
|
||||
"[ lib] ERROR, %u, %s.",
|
||||
(uint32_t)Result,
|
||||
"Resolving hostname to IP");
|
||||
// arg2 = arg2 = (uint32_t)Result = arg2
|
||||
// arg3 = arg3 = "Resolving hostname to IP" = arg3
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_DATAPATH_EPOLL_C, LibraryErrorStatus,
|
||||
TP_ARGS(
|
||||
unsigned int, arg2,
|
||||
const char *, arg3),
|
||||
TP_FIELDS(
|
||||
ctf_integer(unsigned int, arg2, arg2)
|
||||
ctf_string(arg3, arg3)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathErrorStatus
|
||||
// [data][%p] ERROR, %u, %s.
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef CLOG_DO_NOT_INCLUDE_HEADER
|
||||
#include <clog.h>
|
||||
#endif
|
||||
#undef TRACEPOINT_PROVIDER
|
||||
#define TRACEPOINT_PROVIDER CLOG_DATAPATH_LINUX_C
|
||||
#undef TRACEPOINT_PROBE_DYNAMIC_LINKAGE
|
||||
#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
|
||||
#undef TRACEPOINT_INCLUDE
|
||||
#define TRACEPOINT_INCLUDE "datapath_linux.c.clog.h.lttng.h"
|
||||
#if !defined(DEF_CLOG_DATAPATH_LINUX_C) || defined(TRACEPOINT_HEADER_MULTI_READ)
|
||||
#define DEF_CLOG_DATAPATH_LINUX_C
|
||||
#include <lttng/tracepoint.h>
|
||||
#define __int64 __int64_t
|
||||
#include "datapath_linux.c.clog.h.lttng.h"
|
||||
#endif
|
||||
#include <lttng/tracepoint-event.h>
|
||||
#ifndef _clog_MACRO_QuicTraceLogError
|
||||
#define _clog_MACRO_QuicTraceLogError 1
|
||||
#define QuicTraceLogError(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
|
||||
#endif
|
||||
#ifndef _clog_MACRO_QuicTraceEvent
|
||||
#define _clog_MACRO_QuicTraceEvent 1
|
||||
#define QuicTraceEvent(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathResolveHostNameFailed
|
||||
// [%p] Couldn't resolve hostname '%s' to an IP address
|
||||
// QuicTraceLogError(
|
||||
DatapathResolveHostNameFailed,
|
||||
"[%p] Couldn't resolve hostname '%s' to an IP address",
|
||||
Datapath,
|
||||
HostName);
|
||||
// arg2 = arg2 = Datapath = arg2
|
||||
// arg3 = arg3 = HostName = arg3
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_4_ARGS_TRACE_DatapathResolveHostNameFailed
|
||||
#define _clog_4_ARGS_TRACE_DatapathResolveHostNameFailed(uniqueId, encoded_arg_string, arg2, arg3)\
|
||||
tracepoint(CLOG_DATAPATH_LINUX_C, DatapathResolveHostNameFailed , arg2, arg3);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for LibraryErrorStatus
|
||||
// [ lib] ERROR, %u, %s.
|
||||
// QuicTraceEvent(
|
||||
LibraryErrorStatus,
|
||||
"[ lib] ERROR, %u, %s.",
|
||||
(uint32_t)Result,
|
||||
"Resolving hostname to IP");
|
||||
// arg2 = arg2 = (uint32_t)Result = arg2
|
||||
// arg3 = arg3 = "Resolving hostname to IP" = arg3
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_4_ARGS_TRACE_LibraryErrorStatus
|
||||
#define _clog_4_ARGS_TRACE_LibraryErrorStatus(uniqueId, encoded_arg_string, arg2, arg3)\
|
||||
tracepoint(CLOG_DATAPATH_LINUX_C, LibraryErrorStatus , arg2, arg3);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#ifdef CLOG_INLINE_IMPLEMENTATION
|
||||
#include "quic.clog_datapath_linux.c.clog.h.c"
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathResolveHostNameFailed
|
||||
// [%p] Couldn't resolve hostname '%s' to an IP address
|
||||
// QuicTraceLogError(
|
||||
DatapathResolveHostNameFailed,
|
||||
"[%p] Couldn't resolve hostname '%s' to an IP address",
|
||||
Datapath,
|
||||
HostName);
|
||||
// arg2 = arg2 = Datapath = arg2
|
||||
// arg3 = arg3 = HostName = arg3
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_DATAPATH_LINUX_C, DatapathResolveHostNameFailed,
|
||||
TP_ARGS(
|
||||
const void *, arg2,
|
||||
const char *, arg3),
|
||||
TP_FIELDS(
|
||||
ctf_integer_hex(uint64_t, arg2, arg2)
|
||||
ctf_string(arg3, arg3)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for LibraryErrorStatus
|
||||
// [ lib] ERROR, %u, %s.
|
||||
// QuicTraceEvent(
|
||||
LibraryErrorStatus,
|
||||
"[ lib] ERROR, %u, %s.",
|
||||
(uint32_t)Result,
|
||||
"Resolving hostname to IP");
|
||||
// arg2 = arg2 = (uint32_t)Result = arg2
|
||||
// arg3 = arg3 = "Resolving hostname to IP" = arg3
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_DATAPATH_LINUX_C, LibraryErrorStatus,
|
||||
TP_ARGS(
|
||||
unsigned int, arg2,
|
||||
const char *, arg3),
|
||||
TP_FIELDS(
|
||||
ctf_integer(unsigned int, arg2, arg2)
|
||||
ctf_string(arg3, arg3)
|
||||
)
|
||||
)
|
|
@ -61,28 +61,6 @@ tracepoint(CLOG_DATAPATH_RAW_LINUX_C, LibraryErrorStatus , arg2, arg3);\
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathCreated
|
||||
// [data][%p] Created, local=%!ADDR!, remote=%!ADDR!
|
||||
// QuicTraceEvent(
|
||||
DatapathCreated,
|
||||
"[data][%p] Created, local=%!ADDR!, remote=%!ADDR!",
|
||||
*NewSocket,
|
||||
CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress),
|
||||
CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress));
|
||||
// arg2 = arg2 = *NewSocket = arg2
|
||||
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress) = arg3
|
||||
// arg4 = arg4 = CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress) = arg4
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_7_ARGS_TRACE_DatapathCreated
|
||||
#define _clog_7_ARGS_TRACE_DatapathCreated(uniqueId, encoded_arg_string, arg2, arg3, arg3_len, arg4, arg4_len)\
|
||||
tracepoint(CLOG_DATAPATH_RAW_LINUX_C, DatapathCreated , arg2, arg3_len, arg3, arg4_len, arg4);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathRecv
|
||||
// [data][%p] Recv %u bytes (segment=%hu) Src=%!ADDR! Dst=%!ADDR!
|
||||
|
|
|
@ -47,37 +47,6 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_LINUX_C, LibraryErrorStatus,
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathCreated
|
||||
// [data][%p] Created, local=%!ADDR!, remote=%!ADDR!
|
||||
// QuicTraceEvent(
|
||||
DatapathCreated,
|
||||
"[data][%p] Created, local=%!ADDR!, remote=%!ADDR!",
|
||||
*NewSocket,
|
||||
CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress),
|
||||
CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress));
|
||||
// arg2 = arg2 = *NewSocket = arg2
|
||||
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress) = arg3
|
||||
// arg4 = arg4 = CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress) = arg4
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_LINUX_C, DatapathCreated,
|
||||
TP_ARGS(
|
||||
const void *, arg2,
|
||||
unsigned int, arg3_len,
|
||||
const void *, arg3,
|
||||
unsigned int, arg4_len,
|
||||
const void *, arg4),
|
||||
TP_FIELDS(
|
||||
ctf_integer_hex(uint64_t, arg2, arg2)
|
||||
ctf_integer(unsigned int, arg3_len, arg3_len)
|
||||
ctf_sequence(char, arg3, arg3, unsigned int, arg3_len)
|
||||
ctf_integer(unsigned int, arg4_len, arg4_len)
|
||||
ctf_sequence(char, arg4, arg4, unsigned int, arg4_len)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathRecv
|
||||
// [data][%p] Recv %u bytes (segment=%hu) Src=%!ADDR! Dst=%!ADDR!
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
#include "datapath_raw_socket_win.c.clog.h.lttng.h"
|
||||
#endif
|
||||
#include <lttng/tracepoint-event.h>
|
||||
#ifndef _clog_MACRO_QuicTraceLogVerbose
|
||||
#define _clog_MACRO_QuicTraceLogVerbose 1
|
||||
#define QuicTraceLogVerbose(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
|
||||
#endif
|
||||
#ifndef _clog_MACRO_QuicTraceLogConnInfo
|
||||
#define _clog_MACRO_QuicTraceLogConnInfo 1
|
||||
#define QuicTraceLogConnInfo(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
|
||||
|
@ -25,6 +29,26 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathTcpAuxBinding
|
||||
// [data][%p] Binding TCP socket to %s
|
||||
// QuicTraceLogVerbose(
|
||||
DatapathTcpAuxBinding,
|
||||
"[data][%p] Binding TCP socket to %s",
|
||||
Socket,
|
||||
LocalAddressString.Address);
|
||||
// arg2 = arg2 = Socket = arg2
|
||||
// arg3 = arg3 = LocalAddressString.Address = arg3
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_4_ARGS_TRACE_DatapathTcpAuxBinding
|
||||
#define _clog_4_ARGS_TRACE_DatapathTcpAuxBinding(uniqueId, encoded_arg_string, arg2, arg3)\
|
||||
tracepoint(CLOG_DATAPATH_RAW_SOCKET_WIN_C, DatapathTcpAuxBinding , arg2, arg3);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for RouteResolutionStart
|
||||
// [conn][%p] Starting to look up neighbor on Path[%hhu] with status %u
|
||||
|
|
|
@ -1,6 +1,29 @@
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathTcpAuxBinding
|
||||
// [data][%p] Binding TCP socket to %s
|
||||
// QuicTraceLogVerbose(
|
||||
DatapathTcpAuxBinding,
|
||||
"[data][%p] Binding TCP socket to %s",
|
||||
Socket,
|
||||
LocalAddressString.Address);
|
||||
// arg2 = arg2 = Socket = arg2
|
||||
// arg3 = arg3 = LocalAddressString.Address = arg3
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_WIN_C, DatapathTcpAuxBinding,
|
||||
TP_ARGS(
|
||||
const void *, arg2,
|
||||
const char *, arg3),
|
||||
TP_FIELDS(
|
||||
ctf_integer_hex(uint64_t, arg2, arg2)
|
||||
ctf_string(arg3, arg3)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for RouteResolutionStart
|
||||
// [conn][%p] Starting to look up neighbor on Path[%hhu] with status %u
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
#include "datapath_raw_win.c.clog.h.lttng.h"
|
||||
#endif
|
||||
#include <lttng/tracepoint-event.h>
|
||||
#ifndef _clog_MACRO_QuicTraceLogError
|
||||
#define _clog_MACRO_QuicTraceLogError 1
|
||||
#define QuicTraceLogError(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
|
||||
#endif
|
||||
#ifndef _clog_MACRO_QuicTraceEvent
|
||||
#define _clog_MACRO_QuicTraceEvent 1
|
||||
#define QuicTraceEvent(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
|
||||
|
@ -25,26 +21,6 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathResolveHostNameFailed
|
||||
// [%p] Couldn't resolve hostname '%s' to an IP address
|
||||
// QuicTraceLogError(
|
||||
DatapathResolveHostNameFailed,
|
||||
"[%p] Couldn't resolve hostname '%s' to an IP address",
|
||||
Datapath,
|
||||
HostName);
|
||||
// arg2 = arg2 = Datapath = arg2
|
||||
// arg3 = arg3 = HostName = arg3
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_4_ARGS_TRACE_DatapathResolveHostNameFailed
|
||||
#define _clog_4_ARGS_TRACE_DatapathResolveHostNameFailed(uniqueId, encoded_arg_string, arg2, arg3)\
|
||||
tracepoint(CLOG_DATAPATH_RAW_WIN_C, DatapathResolveHostNameFailed , arg2, arg3);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for AllocFailure
|
||||
// Allocation of '%s' failed. (%llu bytes)
|
||||
|
@ -85,46 +61,6 @@ tracepoint(CLOG_DATAPATH_RAW_WIN_C, LibraryErrorStatus , arg2, arg3);\
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for LibraryError
|
||||
// [ lib] ERROR, %s.
|
||||
// QuicTraceEvent(
|
||||
LibraryError,
|
||||
"[ lib] ERROR, %s.",
|
||||
"Resolving hostname to IP");
|
||||
// arg2 = arg2 = "Resolving hostname to IP" = arg2
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_3_ARGS_TRACE_LibraryError
|
||||
#define _clog_3_ARGS_TRACE_LibraryError(uniqueId, encoded_arg_string, arg2)\
|
||||
tracepoint(CLOG_DATAPATH_RAW_WIN_C, LibraryError , arg2);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathCreated
|
||||
// [data][%p] Created, local=%!ADDR!, remote=%!ADDR!
|
||||
// QuicTraceEvent(
|
||||
DatapathCreated,
|
||||
"[data][%p] Created, local=%!ADDR!, remote=%!ADDR!",
|
||||
*NewSocket,
|
||||
CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress),
|
||||
CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress));
|
||||
// arg2 = arg2 = *NewSocket = arg2
|
||||
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress) = arg3
|
||||
// arg4 = arg4 = CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress) = arg4
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_7_ARGS_TRACE_DatapathCreated
|
||||
#define _clog_7_ARGS_TRACE_DatapathCreated(uniqueId, encoded_arg_string, arg2, arg3, arg3_len, arg4, arg4_len)\
|
||||
tracepoint(CLOG_DATAPATH_RAW_WIN_C, DatapathCreated , arg2, arg3_len, arg3, arg4_len, arg4);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathRecv
|
||||
// [data][%p] Recv %u bytes (segment=%hu) Src=%!ADDR! Dst=%!ADDR!
|
||||
|
|
|
@ -1,29 +1,6 @@
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathResolveHostNameFailed
|
||||
// [%p] Couldn't resolve hostname '%s' to an IP address
|
||||
// QuicTraceLogError(
|
||||
DatapathResolveHostNameFailed,
|
||||
"[%p] Couldn't resolve hostname '%s' to an IP address",
|
||||
Datapath,
|
||||
HostName);
|
||||
// arg2 = arg2 = Datapath = arg2
|
||||
// arg3 = arg3 = HostName = arg3
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_WIN_C, DatapathResolveHostNameFailed,
|
||||
TP_ARGS(
|
||||
const void *, arg2,
|
||||
const char *, arg3),
|
||||
TP_FIELDS(
|
||||
ctf_integer_hex(uint64_t, arg2, arg2)
|
||||
ctf_string(arg3, arg3)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for AllocFailure
|
||||
// Allocation of '%s' failed. (%llu bytes)
|
||||
|
@ -70,56 +47,6 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_WIN_C, LibraryErrorStatus,
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for LibraryError
|
||||
// [ lib] ERROR, %s.
|
||||
// QuicTraceEvent(
|
||||
LibraryError,
|
||||
"[ lib] ERROR, %s.",
|
||||
"Resolving hostname to IP");
|
||||
// arg2 = arg2 = "Resolving hostname to IP" = arg2
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_WIN_C, LibraryError,
|
||||
TP_ARGS(
|
||||
const char *, arg2),
|
||||
TP_FIELDS(
|
||||
ctf_string(arg2, arg2)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathCreated
|
||||
// [data][%p] Created, local=%!ADDR!, remote=%!ADDR!
|
||||
// QuicTraceEvent(
|
||||
DatapathCreated,
|
||||
"[data][%p] Created, local=%!ADDR!, remote=%!ADDR!",
|
||||
*NewSocket,
|
||||
CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress),
|
||||
CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress));
|
||||
// arg2 = arg2 = *NewSocket = arg2
|
||||
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress) = arg3
|
||||
// arg4 = arg4 = CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress) = arg4
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_WIN_C, DatapathCreated,
|
||||
TP_ARGS(
|
||||
const void *, arg2,
|
||||
unsigned int, arg3_len,
|
||||
const void *, arg3,
|
||||
unsigned int, arg4_len,
|
||||
const void *, arg4),
|
||||
TP_FIELDS(
|
||||
ctf_integer_hex(uint64_t, arg2, arg2)
|
||||
ctf_integer(unsigned int, arg3_len, arg3_len)
|
||||
ctf_sequence(char, arg3, arg3, unsigned int, arg3_len)
|
||||
ctf_integer(unsigned int, arg4_len, arg4_len)
|
||||
ctf_sequence(char, arg4, arg4, unsigned int, arg4_len)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathRecv
|
||||
// [data][%p] Recv %u bytes (segment=%hu) Src=%!ADDR! Dst=%!ADDR!
|
||||
|
|
|
@ -22,10 +22,6 @@
|
|||
#define _clog_MACRO_QuicTraceLogVerbose 1
|
||||
#define QuicTraceLogVerbose(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
|
||||
#endif
|
||||
#ifndef _clog_MACRO_QuicTraceLogError
|
||||
#define _clog_MACRO_QuicTraceLogError 1
|
||||
#define QuicTraceLogError(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
|
||||
#endif
|
||||
#ifndef _clog_MACRO_QuicTraceEvent
|
||||
#define _clog_MACRO_QuicTraceEvent 1
|
||||
#define QuicTraceEvent(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
|
||||
|
@ -255,26 +251,6 @@ tracepoint(CLOG_DATAPATH_WINUSER_C, DatapathTooLarge , arg2, arg3_len, arg3);\
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathResolveHostNameFailed
|
||||
// [%p] Couldn't resolve hostname '%s' to an IP address
|
||||
// QuicTraceLogError(
|
||||
DatapathResolveHostNameFailed,
|
||||
"[%p] Couldn't resolve hostname '%s' to an IP address",
|
||||
Datapath,
|
||||
HostName);
|
||||
// arg2 = arg2 = Datapath = arg2
|
||||
// arg3 = arg3 = HostName = arg3
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_4_ARGS_TRACE_DatapathResolveHostNameFailed
|
||||
#define _clog_4_ARGS_TRACE_DatapathResolveHostNameFailed(uniqueId, encoded_arg_string, arg2, arg3)\
|
||||
tracepoint(CLOG_DATAPATH_WINUSER_C, DatapathResolveHostNameFailed , arg2, arg3);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for LibraryErrorStatus
|
||||
// [ lib] ERROR, %u, %s.
|
||||
|
@ -315,24 +291,6 @@ tracepoint(CLOG_DATAPATH_WINUSER_C, AllocFailure , arg2, arg3);\
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for LibraryError
|
||||
// [ lib] ERROR, %s.
|
||||
// QuicTraceEvent(
|
||||
LibraryError,
|
||||
"[ lib] ERROR, %s.",
|
||||
"No local unicast addresses found");
|
||||
// arg2 = arg2 = "No local unicast addresses found" = arg2
|
||||
----------------------------------------------------------*/
|
||||
#ifndef _clog_3_ARGS_TRACE_LibraryError
|
||||
#define _clog_3_ARGS_TRACE_LibraryError(uniqueId, encoded_arg_string, arg2)\
|
||||
tracepoint(CLOG_DATAPATH_WINUSER_C, LibraryError , arg2);\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathErrorStatus
|
||||
// [data][%p] ERROR, %u, %s.
|
||||
|
|
|
@ -245,29 +245,6 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_WINUSER_C, DatapathTooLarge,
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathResolveHostNameFailed
|
||||
// [%p] Couldn't resolve hostname '%s' to an IP address
|
||||
// QuicTraceLogError(
|
||||
DatapathResolveHostNameFailed,
|
||||
"[%p] Couldn't resolve hostname '%s' to an IP address",
|
||||
Datapath,
|
||||
HostName);
|
||||
// arg2 = arg2 = Datapath = arg2
|
||||
// arg3 = arg3 = HostName = arg3
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_DATAPATH_WINUSER_C, DatapathResolveHostNameFailed,
|
||||
TP_ARGS(
|
||||
const void *, arg2,
|
||||
const char *, arg3),
|
||||
TP_FIELDS(
|
||||
ctf_integer_hex(uint64_t, arg2, arg2)
|
||||
ctf_string(arg3, arg3)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for LibraryErrorStatus
|
||||
// [ lib] ERROR, %u, %s.
|
||||
|
@ -314,25 +291,6 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_WINUSER_C, AllocFailure,
|
|||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for LibraryError
|
||||
// [ lib] ERROR, %s.
|
||||
// QuicTraceEvent(
|
||||
LibraryError,
|
||||
"[ lib] ERROR, %s.",
|
||||
"No local unicast addresses found");
|
||||
// arg2 = arg2 = "No local unicast addresses found" = arg2
|
||||
----------------------------------------------------------*/
|
||||
TRACEPOINT_EVENT(CLOG_DATAPATH_WINUSER_C, LibraryError,
|
||||
TP_ARGS(
|
||||
const char *, arg2),
|
||||
TP_FIELDS(
|
||||
ctf_string(arg2, arg2)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Decoder Ring for DatapathErrorStatus
|
||||
// [data][%p] ERROR, %u, %s.
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#include <clog.h>
|
||||
#ifdef BUILDING_TRACEPOINT_PROVIDER
|
||||
#define TRACEPOINT_CREATE_PROBES
|
||||
#else
|
||||
#define TRACEPOINT_DEFINE
|
||||
#endif
|
||||
#include "datapath_linux.c.clog.h"
|
|
@ -125,6 +125,7 @@ PacketSizeFromUdpPayloadSize(
|
|||
// The top level datapath handle type.
|
||||
//
|
||||
typedef struct CXPLAT_DATAPATH CXPLAT_DATAPATH;
|
||||
typedef struct CXPLAT_DATAPATH_RAW CXPLAT_DATAPATH_RAW;
|
||||
|
||||
//
|
||||
// Represents a UDP or TCP abstraction.
|
||||
|
@ -180,6 +181,8 @@ typedef struct CXPLAT_ROUTE {
|
|||
CXPLAT_ROUTE_STATE State;
|
||||
CXPLAT_RAW_TCP_STATE TcpState;
|
||||
|
||||
uint16_t DatapathType; // CXPLAT_DATAPATH_TYPE
|
||||
|
||||
} CXPLAT_ROUTE;
|
||||
|
||||
//
|
||||
|
@ -224,8 +227,9 @@ typedef struct CXPLAT_RECV_DATA {
|
|||
//
|
||||
uint16_t Allocated : 1; // Used for debugging. Set to FALSE on free.
|
||||
uint16_t QueuedOnConnection : 1; // Used for debugging.
|
||||
uint16_t Reserved : 6;
|
||||
uint16_t ReservedEx : 8;
|
||||
uint16_t DatapathType : 2; // CXPLAT_DATAPATH_TYPE
|
||||
uint16_t Reserved : 4; // PACKET_TYPE (at least 3 bits)
|
||||
uint16_t ReservedEx : 8; // Header length
|
||||
|
||||
//
|
||||
// Variable length data (of size `ClientRecvContextLength` passed into
|
||||
|
@ -446,7 +450,8 @@ CxPlatDataPathGetSupportedFeatures(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
CxPlatDataPathIsPaddingPreferred(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
);
|
||||
|
||||
//
|
||||
|
@ -745,13 +750,6 @@ CxPlatResolveRouteComplete(
|
|||
_In_ uint8_t PathId
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
QuicCopyRouteInfo(
|
||||
_Inout_ CXPLAT_ROUTE* DstRoute,
|
||||
_In_ CXPLAT_ROUTE* SrcRoute
|
||||
);
|
||||
|
||||
//
|
||||
// Tries to resolve route and neighbor for the given destination address.
|
||||
//
|
||||
|
|
|
@ -3175,6 +3175,22 @@
|
|||
],
|
||||
"macroName": "QuicTraceLogVerbose"
|
||||
},
|
||||
"DatapathTcpAuxBinding": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "[data][%p] Binding TCP socket to %s",
|
||||
"UniqueId": "DatapathTcpAuxBinding",
|
||||
"splitArgs": [
|
||||
{
|
||||
"DefinationEncoding": "p",
|
||||
"MacroVariableName": "arg2"
|
||||
},
|
||||
{
|
||||
"DefinationEncoding": "s",
|
||||
"MacroVariableName": "arg3"
|
||||
}
|
||||
],
|
||||
"macroName": "QuicTraceLogVerbose"
|
||||
},
|
||||
"DatapathTooLarge": {
|
||||
"ModuleProperites": {},
|
||||
"TraceString": "[data][%p] Received larger than expected datagram from %!ADDR!",
|
||||
|
@ -13873,6 +13889,11 @@
|
|||
"TraceID": "DatapathSocketUninitializeComplete",
|
||||
"EncodingString": "[data][%p] Socket uninitialize complete"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "3a4da7bb-462a-a423-bd9e-bcc366e59258",
|
||||
"TraceID": "DatapathTcpAuxBinding",
|
||||
"EncodingString": "[data][%p] Binding TCP socket to %s"
|
||||
},
|
||||
{
|
||||
"UniquenessHash": "a07c9538-e6d7-3c41-1367-ce58f2df4d9e",
|
||||
"TraceID": "DatapathTooLarge",
|
||||
|
|
|
@ -12,20 +12,16 @@ endif()
|
|||
set(SOURCES crypt.c hashtable.c pcp.c platform_worker.c toeplitz.c)
|
||||
|
||||
if("${CX_PLATFORM}" STREQUAL "windows")
|
||||
set(SOURCES ${SOURCES} platform_winuser.c storage_winuser.c)
|
||||
if(QUIC_USE_XDP)
|
||||
set(SOURCES ${SOURCES} datapath_raw_win.c datapath_raw_socket.c datapath_raw_socket_win.c datapath_raw_xdp_win.c)
|
||||
set(SOURCES ${SOURCES} platform_winuser.c storage_winuser.c datapath_win.c datapath_winuser.c)
|
||||
if(QUIC_UWP_BUILD)
|
||||
set(SOURCES ${SOURCES} datapath_raw_dummy.c)
|
||||
else()
|
||||
set(SOURCES ${SOURCES} datapath_winuser.c)
|
||||
set(SOURCES ${SOURCES} datapath_raw_win.c datapath_raw_socket.c datapath_raw_socket_win.c datapath_raw_xdp_win.c)
|
||||
endif()
|
||||
else()
|
||||
set(SOURCES ${SOURCES} inline.c platform_posix.c storage_posix.c cgroup.c)
|
||||
if(CX_PLATFORM STREQUAL "linux" AND NOT CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
if(QUIC_USE_XDP)
|
||||
set(SOURCES ${SOURCES} datapath_raw_linux.c datapath_raw_socket.c datapath_raw_socket_linux.c datapath_raw_xdp_linux.c)
|
||||
else()
|
||||
set(SOURCES ${SOURCES} datapath_epoll.c)
|
||||
endif()
|
||||
set(SOURCES ${SOURCES} datapath_raw_linux.c datapath_raw_socket.c datapath_raw_socket_linux.c datapath_raw_xdp_linux.c datapath_epoll.c datapath_linux.c)
|
||||
else()
|
||||
set(SOURCES ${SOURCES} datapath_kqueue.c)
|
||||
endif()
|
||||
|
@ -50,7 +46,7 @@ endif()
|
|||
|
||||
add_library(platform STATIC ${SOURCES})
|
||||
|
||||
if ("${CX_PLATFORM}" STREQUAL "windows" AND QUIC_USE_XDP)
|
||||
if("${CX_PLATFORM}" STREQUAL "windows")
|
||||
target_link_libraries(
|
||||
platform
|
||||
PUBLIC
|
||||
|
@ -68,14 +64,12 @@ target_link_libraries(platform PRIVATE warnings main_binary_link_args)
|
|||
|
||||
set_property(TARGET platform PROPERTY FOLDER "${QUIC_FOLDER_PREFIX}libraries")
|
||||
|
||||
if ("${CX_PLATFORM}" STREQUAL "windows" AND QUIC_USE_XDP)
|
||||
if ("${CX_PLATFORM}" STREQUAL "windows")
|
||||
target_include_directories(
|
||||
platform
|
||||
PRIVATE
|
||||
${EXTRA_PLATFORM_INCLUDE_DIRECTORIES}
|
||||
${PROJECT_SOURCE_DIR}/artifacts/xdp/include)
|
||||
else()
|
||||
target_include_directories(platform PRIVATE ${EXTRA_PLATFORM_INCLUDE_DIRECTORIES})
|
||||
endif()
|
||||
|
||||
if (MSVC AND (QUIC_TLS STREQUAL "openssl" OR QUIC_TLS STREQUAL "schannel") AND NOT QUIC_ENABLE_SANITIZERS)
|
||||
|
|
|
@ -200,249 +200,6 @@ typedef struct CXPLAT_RECV_MSG_CONTROL_BUFFER {
|
|||
2 * CMSG_SPACE(sizeof(int))];
|
||||
} CXPLAT_RECV_MSG_CONTROL_BUFFER;
|
||||
|
||||
typedef struct CXPLAT_DATAPATH_PARTITION CXPLAT_DATAPATH_PARTITION;
|
||||
|
||||
//
|
||||
// Socket context.
|
||||
//
|
||||
typedef struct QUIC_CACHEALIGN CXPLAT_SOCKET_CONTEXT {
|
||||
|
||||
//
|
||||
// The datapath binding this socket context belongs to.
|
||||
//
|
||||
CXPLAT_SOCKET* Binding;
|
||||
|
||||
//
|
||||
// The datapath proc context this socket belongs to.
|
||||
//
|
||||
CXPLAT_DATAPATH_PARTITION* DatapathPartition;
|
||||
|
||||
//
|
||||
// The socket FD used by this socket context.
|
||||
//
|
||||
int SocketFd;
|
||||
|
||||
//
|
||||
// The submission queue event for shutdown.
|
||||
//
|
||||
DATAPATH_SQE ShutdownSqe;
|
||||
|
||||
//
|
||||
// The submission queue event for IO.
|
||||
//
|
||||
DATAPATH_SQE IoSqe;
|
||||
|
||||
//
|
||||
// The submission queue event for flushing the send queue.
|
||||
//
|
||||
DATAPATH_SQE FlushTxSqe;
|
||||
|
||||
//
|
||||
// The head of list containg all pending sends on this socket.
|
||||
//
|
||||
CXPLAT_LIST_ENTRY TxQueue;
|
||||
|
||||
//
|
||||
// Lock around the PendingSendData list.
|
||||
//
|
||||
CXPLAT_LOCK TxQueueLock;
|
||||
|
||||
//
|
||||
// Rundown for synchronizing clean up with upcalls.
|
||||
//
|
||||
CXPLAT_RUNDOWN_REF UpcallRundown;
|
||||
|
||||
//
|
||||
// Inidicates the SQEs have been initialized.
|
||||
//
|
||||
BOOLEAN SqeInitialized : 1;
|
||||
|
||||
//
|
||||
// Inidicates if the socket has started IO processing.
|
||||
//
|
||||
BOOLEAN IoStarted : 1;
|
||||
|
||||
#if DEBUG
|
||||
uint8_t Uninitialized : 1;
|
||||
uint8_t Freed : 1;
|
||||
#endif
|
||||
|
||||
} CXPLAT_SOCKET_CONTEXT;
|
||||
|
||||
//
|
||||
// Datapath binding.
|
||||
//
|
||||
typedef struct CXPLAT_SOCKET {
|
||||
|
||||
//
|
||||
// A pointer to datapath object.
|
||||
//
|
||||
CXPLAT_DATAPATH* Datapath;
|
||||
|
||||
//
|
||||
// The client context for this binding.
|
||||
//
|
||||
void *ClientContext;
|
||||
|
||||
//
|
||||
// The local address for the binding.
|
||||
//
|
||||
QUIC_ADDR LocalAddress;
|
||||
|
||||
//
|
||||
// The remote address for the binding.
|
||||
//
|
||||
QUIC_ADDR RemoteAddress;
|
||||
|
||||
//
|
||||
// Synchronization mechanism for cleanup.
|
||||
//
|
||||
CXPLAT_REF_COUNT RefCount;
|
||||
|
||||
//
|
||||
// The MTU for this binding.
|
||||
//
|
||||
uint16_t Mtu;
|
||||
|
||||
//
|
||||
// Indicates the binding connected to a remote IP address.
|
||||
//
|
||||
BOOLEAN Connected : 1;
|
||||
|
||||
//
|
||||
// Flag indicates the socket has a default remote destination.
|
||||
//
|
||||
BOOLEAN HasFixedRemoteAddress : 1;
|
||||
|
||||
//
|
||||
// Flag indicates the binding is being used for PCP.
|
||||
//
|
||||
BOOLEAN PcpBinding : 1;
|
||||
|
||||
#if DEBUG
|
||||
uint8_t Uninitialized : 1;
|
||||
uint8_t Freed : 1;
|
||||
#endif
|
||||
|
||||
//
|
||||
// Set of socket contexts one per proc.
|
||||
//
|
||||
CXPLAT_SOCKET_CONTEXT SocketContexts[];
|
||||
|
||||
} CXPLAT_SOCKET;
|
||||
|
||||
//
|
||||
// A per processor datapath context.
|
||||
//
|
||||
typedef struct QUIC_CACHEALIGN CXPLAT_DATAPATH_PARTITION {
|
||||
|
||||
//
|
||||
// A pointer to the datapath.
|
||||
//
|
||||
CXPLAT_DATAPATH* Datapath;
|
||||
|
||||
//
|
||||
// The event queue for this proc context.
|
||||
//
|
||||
CXPLAT_EVENTQ* EventQ;
|
||||
|
||||
//
|
||||
// Synchronization mechanism for cleanup.
|
||||
//
|
||||
CXPLAT_REF_COUNT RefCount;
|
||||
|
||||
//
|
||||
// The ideal processor of the context.
|
||||
//
|
||||
uint16_t PartitionIndex;
|
||||
|
||||
#if DEBUG
|
||||
uint8_t Uninitialized : 1;
|
||||
#endif
|
||||
|
||||
//
|
||||
// Pool of receive packet contexts and buffers to be shared by all sockets
|
||||
// on this core.
|
||||
//
|
||||
CXPLAT_POOL RecvBlockPool;
|
||||
|
||||
//
|
||||
// Pool of send packet contexts and buffers to be shared by all sockets
|
||||
// on this core.
|
||||
//
|
||||
CXPLAT_POOL SendBlockPool;
|
||||
|
||||
} CXPLAT_DATAPATH_PARTITION;
|
||||
|
||||
//
|
||||
// Represents a datapath object.
|
||||
//
|
||||
|
||||
typedef struct CXPLAT_DATAPATH {
|
||||
|
||||
//
|
||||
// UDP handlers.
|
||||
//
|
||||
CXPLAT_UDP_DATAPATH_CALLBACKS UdpHandlers;
|
||||
|
||||
//
|
||||
// Synchronization mechanism for cleanup.
|
||||
//
|
||||
CXPLAT_REF_COUNT RefCount;
|
||||
|
||||
//
|
||||
// Set of supported features.
|
||||
//
|
||||
uint32_t Features;
|
||||
|
||||
//
|
||||
// The proc count to create per proc datapath state.
|
||||
//
|
||||
uint32_t PartitionCount;
|
||||
|
||||
//
|
||||
// The length of the CXPLAT_SEND_DATA. Calculated based on the support level
|
||||
// for GSO. No GSO support requires a larger send data to hold the extra
|
||||
// iovec structs.
|
||||
//
|
||||
uint32_t SendDataSize;
|
||||
|
||||
//
|
||||
// When not using GSO, we preallocate multiple iovec structs to use with
|
||||
// sendmmsg (to simulate GSO).
|
||||
//
|
||||
uint32_t SendIoVecCount;
|
||||
|
||||
//
|
||||
// The length of the CXPLAT_RECV_DATA and client data part of the
|
||||
// DATAPATH_RX_IO_BLOCK.
|
||||
//
|
||||
uint32_t RecvBlockStride;
|
||||
|
||||
//
|
||||
// The offset of the raw buffer in the DATAPATH_RX_IO_BLOCK.
|
||||
//
|
||||
uint32_t RecvBlockBufferOffset;
|
||||
|
||||
//
|
||||
// The total length of the DATAPATH_RX_IO_BLOCK. Calculated based on the
|
||||
// support level for GRO. No GRO only uses a single CXPLAT_RECV_DATA and
|
||||
// client data, while GRO allows for multiple.
|
||||
//
|
||||
uint32_t RecvBlockSize;
|
||||
|
||||
#if DEBUG
|
||||
uint8_t Uninitialized : 1;
|
||||
uint8_t Freed : 1;
|
||||
#endif
|
||||
|
||||
//
|
||||
// The per proc datapath contexts.
|
||||
//
|
||||
CXPLAT_DATAPATH_PARTITION Partitions[];
|
||||
|
||||
} CXPLAT_DATAPATH;
|
||||
|
||||
#ifdef DEBUG
|
||||
#define CXPLAT_DBG_ASSERT_CMSG(CMsg, type) \
|
||||
if (CMsg->cmsg_len < CMSG_LEN(sizeof(type))) { \
|
||||
|
@ -601,16 +358,16 @@ CxPlatProcessorContextInitialize(
|
|||
}
|
||||
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathInitialize(
|
||||
DataPathInitialize(
|
||||
_In_ uint32_t ClientRecvDataLength,
|
||||
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
|
||||
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
|
||||
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
|
||||
_Out_ CXPLAT_DATAPATH** NewDataPath
|
||||
_Out_ CXPLAT_DATAPATH** NewDatapath
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(TcpCallbacks);
|
||||
if (NewDataPath == NULL) {
|
||||
if (NewDatapath == NULL) {
|
||||
return QUIC_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (UdpCallbacks != NULL) {
|
||||
|
@ -658,7 +415,7 @@ CxPlatDataPathInitialize(
|
|||
}
|
||||
|
||||
CXPLAT_FRE_ASSERT(CxPlatRundownAcquire(&CxPlatWorkerRundown));
|
||||
*NewDataPath = Datapath;
|
||||
*NewDatapath = Datapath;
|
||||
|
||||
return QUIC_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -698,7 +455,7 @@ CxPlatProcessorContextRelease(
|
|||
}
|
||||
|
||||
void
|
||||
CxPlatDataPathUninitialize(
|
||||
DataPathUninitialize(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
)
|
||||
{
|
||||
|
@ -716,7 +473,7 @@ CxPlatDataPathUninitialize(
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDataPathUpdateConfig(
|
||||
DataPathUpdateConfig(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ QUIC_EXECUTION_CONFIG* Config
|
||||
)
|
||||
|
@ -727,7 +484,7 @@ CxPlatDataPathUpdateConfig(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
uint32_t
|
||||
CxPlatDataPathGetSupportedFeatures(
|
||||
DataPathGetSupportedFeatures(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
)
|
||||
{
|
||||
|
@ -735,155 +492,13 @@ CxPlatDataPathGetSupportedFeatures(
|
|||
}
|
||||
|
||||
BOOLEAN
|
||||
CxPlatDataPathIsPaddingPreferred(
|
||||
DataPathIsPaddingPreferred(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
)
|
||||
{
|
||||
return !!(Datapath->Features & CXPLAT_DATAPATH_FEATURE_SEND_SEGMENTATION);
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatDataPathPopulateTargetAddress(
|
||||
_In_ QUIC_ADDRESS_FAMILY Family,
|
||||
_In_ ADDRINFO* AddrInfo,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
struct sockaddr_in6* SockAddrIn6 = NULL;
|
||||
struct sockaddr_in* SockAddrIn = NULL;
|
||||
|
||||
CxPlatZeroMemory(Address, sizeof(QUIC_ADDR));
|
||||
|
||||
if (AddrInfo->ai_addr->sa_family == AF_INET6) {
|
||||
CXPLAT_DBG_ASSERT(sizeof(struct sockaddr_in6) == AddrInfo->ai_addrlen);
|
||||
|
||||
//
|
||||
// Is this a mapped ipv4 one?
|
||||
//
|
||||
|
||||
SockAddrIn6 = (struct sockaddr_in6*)AddrInfo->ai_addr;
|
||||
|
||||
if (Family == QUIC_ADDRESS_FAMILY_UNSPEC && IN6_IS_ADDR_V4MAPPED(&SockAddrIn6->sin6_addr)) {
|
||||
SockAddrIn = &Address->Ipv4;
|
||||
|
||||
//
|
||||
// Get the ipv4 address from the mapped address.
|
||||
//
|
||||
|
||||
SockAddrIn->sin_family = QUIC_ADDRESS_FAMILY_INET;
|
||||
memcpy(&SockAddrIn->sin_addr.s_addr, &SockAddrIn6->sin6_addr.s6_addr[12], 4);
|
||||
SockAddrIn->sin_port = SockAddrIn6->sin6_port;
|
||||
|
||||
return;
|
||||
}
|
||||
Address->Ipv6 = *SockAddrIn6;
|
||||
Address->Ipv6.sin6_family = QUIC_ADDRESS_FAMILY_INET6;
|
||||
return;
|
||||
}
|
||||
|
||||
if (AddrInfo->ai_addr->sa_family == AF_INET) {
|
||||
CXPLAT_DBG_ASSERT(sizeof(struct sockaddr_in) == AddrInfo->ai_addrlen);
|
||||
SockAddrIn = (struct sockaddr_in*)AddrInfo->ai_addr;
|
||||
Address->Ipv4 = *SockAddrIn;
|
||||
Address->Ipv4.sin_family = QUIC_ADDRESS_FAMILY_INET;
|
||||
return;
|
||||
}
|
||||
|
||||
CXPLAT_FRE_ASSERT(FALSE);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
_Success_(QUIC_SUCCEEDED(return))
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathGetLocalAddresses(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_Outptr_ _At_(*Addresses, __drv_allocatesMem(Mem))
|
||||
CXPLAT_ADAPTER_ADDRESS** Addresses,
|
||||
_Out_ uint32_t* AddressesCount
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
*Addresses = NULL;
|
||||
*AddressesCount = 0;
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathGetGatewayAddresses(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_Outptr_ _At_(*GatewayAddresses, __drv_allocatesMem(Mem))
|
||||
QUIC_ADDR** GatewayAddresses,
|
||||
_Out_ uint32_t* GatewayAddressesCount
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
*GatewayAddresses = NULL;
|
||||
*GatewayAddressesCount = 0;
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathResolveAddress(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_z_ const char* HostName,
|
||||
_Inout_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
|
||||
ADDRINFO Hints = {0};
|
||||
ADDRINFO* AddrInfo = NULL;
|
||||
int Result = 0;
|
||||
|
||||
//
|
||||
// Prepopulate hint with input family. It might be unspecified.
|
||||
//
|
||||
Hints.ai_family = Address->Ip.sa_family;
|
||||
if (Hints.ai_family == QUIC_ADDRESS_FAMILY_INET6) {
|
||||
Hints.ai_family = AF_INET6;
|
||||
}
|
||||
|
||||
//
|
||||
// Try numeric name first.
|
||||
//
|
||||
Hints.ai_flags = AI_NUMERICHOST;
|
||||
Result = getaddrinfo(HostName, NULL, &Hints, &AddrInfo);
|
||||
if (Result == 0) {
|
||||
CxPlatDataPathPopulateTargetAddress(Hints.ai_family, AddrInfo, Address);
|
||||
freeaddrinfo(AddrInfo);
|
||||
AddrInfo = NULL;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Try canonical host name.
|
||||
//
|
||||
Hints.ai_flags = AI_CANONNAME;
|
||||
Result = getaddrinfo(HostName, NULL, &Hints, &AddrInfo);
|
||||
if (Result == 0) {
|
||||
CxPlatDataPathPopulateTargetAddress(Hints.ai_family, AddrInfo, Address);
|
||||
freeaddrinfo(AddrInfo);
|
||||
AddrInfo = NULL;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
QuicTraceEvent(
|
||||
LibraryErrorStatus,
|
||||
"[ lib] ERROR, %u, %s.",
|
||||
(uint32_t)Result,
|
||||
"Resolving hostname to IP");
|
||||
QuicTraceLogError(
|
||||
DatapathResolveHostNameFailed,
|
||||
"[%p] Couldn't resolve hostname '%s' to an IP address",
|
||||
Datapath,
|
||||
HostName);
|
||||
Status = (QUIC_STATUS)Result;
|
||||
|
||||
Exit:
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
QUIC_STATUS
|
||||
CxPlatSocketConfigureRss(
|
||||
_In_ CXPLAT_SOCKET_CONTEXT* SocketContext,
|
||||
|
@ -1471,7 +1086,7 @@ CxPlatSocketContextSetEvents(
|
|||
//
|
||||
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateUdp(
|
||||
SocketCreateUdp(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ const CXPLAT_UDP_CONFIG* Config,
|
||||
_Out_ CXPLAT_SOCKET** NewBinding
|
||||
|
@ -1584,7 +1199,7 @@ Exit:
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateTcp(
|
||||
SocketCreateTcp(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_opt_ const QUIC_ADDR* LocalAddress,
|
||||
_In_ const QUIC_ADDR* RemoteAddress,
|
||||
|
@ -1602,7 +1217,7 @@ CxPlatSocketCreateTcp(
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateTcpListener(
|
||||
SocketCreateTcpListener(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_opt_ const QUIC_ADDR* LocalAddress,
|
||||
_In_opt_ void* CallbackContext,
|
||||
|
@ -1617,8 +1232,8 @@ CxPlatSocketCreateTcpListener(
|
|||
}
|
||||
|
||||
void
|
||||
CxPlatSocketDelete(
|
||||
_Inout_ CXPLAT_SOCKET* Socket
|
||||
SocketDelete(
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Socket != NULL);
|
||||
|
@ -1640,50 +1255,6 @@ CxPlatSocketDelete(
|
|||
}
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketUpdateQeo(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_reads_(OffloadCount)
|
||||
const CXPLAT_QEO_CONNECTION* Offloads,
|
||||
_In_ uint32_t OffloadCount
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Socket);
|
||||
UNREFERENCED_PARAMETER(Offloads);
|
||||
UNREFERENCED_PARAMETER(OffloadCount);
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
CxPlatSocketGetLocalMtu(
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Socket != NULL);
|
||||
return Socket->Mtu;
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatSocketGetLocalAddress(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Socket != NULL);
|
||||
*Address = Socket->LocalAddress;
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatSocketGetRemoteAddress(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Socket != NULL);
|
||||
*Address = Socket->RemoteAddress;
|
||||
}
|
||||
|
||||
//
|
||||
// Receive Path
|
||||
//
|
||||
|
@ -2039,8 +1610,8 @@ CxPlatSocketReceive(
|
|||
}
|
||||
|
||||
void
|
||||
CxPlatRecvDataReturn(
|
||||
_In_opt_ CXPLAT_RECV_DATA* RecvDataChain
|
||||
RecvDataReturn(
|
||||
_In_ CXPLAT_RECV_DATA* RecvDataChain
|
||||
)
|
||||
{
|
||||
CXPLAT_RECV_DATA* Datagram;
|
||||
|
@ -2061,7 +1632,7 @@ CxPlatRecvDataReturn(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
CXPLAT_SEND_DATA*
|
||||
CxPlatSendDataAlloc(
|
||||
SendDataAlloc(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Inout_ CXPLAT_SEND_CONFIG* Config
|
||||
)
|
||||
|
@ -2099,7 +1670,7 @@ CxPlatSendDataAlloc(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSendDataFree(
|
||||
SendDataFree(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
|
@ -2147,7 +1718,7 @@ CxPlatSendDataFinalizeSendBuffer(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
QUIC_BUFFER*
|
||||
CxPlatSendDataAllocBuffer(
|
||||
SendDataAllocBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ uint16_t MaxBufferLength
|
||||
)
|
||||
|
@ -2170,7 +1741,7 @@ CxPlatSendDataAllocBuffer(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSendDataFreeBuffer(
|
||||
SendDataFreeBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ QUIC_BUFFER* Buffer
|
||||
)
|
||||
|
@ -2185,7 +1756,7 @@ CxPlatSendDataFreeBuffer(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
CxPlatSendDataIsFull(
|
||||
SendDataIsFull(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
|
@ -2199,7 +1770,7 @@ CxPlatSendDataSend(
|
|||
);
|
||||
|
||||
QUIC_STATUS
|
||||
CxPlatSocketSend(
|
||||
SocketSend(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ const CXPLAT_ROUTE* Route,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
|
@ -2554,7 +2125,7 @@ CxPlatDataPathSocketProcessIoCompletion(
|
|||
}
|
||||
|
||||
void
|
||||
CxPlatDataPathProcessCqe(
|
||||
DataPathProcessCqe(
|
||||
_In_ CXPLAT_CQE* Cqe
|
||||
)
|
||||
{
|
||||
|
@ -2579,57 +2150,3 @@ CxPlatDataPathProcessCqe(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
QuicCopyRouteInfo(
|
||||
_Inout_ CXPLAT_ROUTE* DstRoute,
|
||||
_In_ CXPLAT_ROUTE* SrcRoute
|
||||
)
|
||||
{
|
||||
*DstRoute = *SrcRoute;
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatResolveRouteComplete(
|
||||
_In_ void* Context,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_reads_bytes_(6) const uint8_t* PhysicalAddress,
|
||||
_In_ uint8_t PathId
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Context);
|
||||
UNREFERENCED_PARAMETER(Route);
|
||||
UNREFERENCED_PARAMETER(PhysicalAddress);
|
||||
UNREFERENCED_PARAMETER(PathId);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatResolveRoute(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_ uint8_t PathId,
|
||||
_In_ void* Context,
|
||||
_In_ CXPLAT_ROUTE_RESOLUTION_CALLBACK_HANDLER Callback
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Socket);
|
||||
UNREFERENCED_PARAMETER(PathId);
|
||||
UNREFERENCED_PARAMETER(Context);
|
||||
UNREFERENCED_PARAMETER(Callback);
|
||||
Route->State = RouteResolved;
|
||||
return QUIC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatUpdateRoute(
|
||||
_Inout_ CXPLAT_ROUTE* DstRoute,
|
||||
_In_ CXPLAT_ROUTE* SrcRoute
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(DstRoute);
|
||||
UNREFERENCED_PARAMETER(SrcRoute);
|
||||
}
|
||||
|
|
|
@ -572,9 +572,11 @@ CxPlatDataPathGetSupportedFeatures(
|
|||
|
||||
BOOLEAN
|
||||
CxPlatDataPathIsPaddingPreferred(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(SendData);
|
||||
return !!(Datapath->Features & CXPLAT_DATAPATH_FEATURE_SEND_SEGMENTATION);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,465 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
Licensed under the MIT License.
|
||||
|
||||
Abstract:
|
||||
|
||||
QUIC Datapath Implementation (User Mode)
|
||||
|
||||
--*/
|
||||
|
||||
#include "platform_internal.h"
|
||||
|
||||
#ifdef QUIC_CLOG
|
||||
#include "datapath_linux.c.clog.h"
|
||||
#endif
|
||||
|
||||
#pragma warning(disable:4116) // unnamed type definition in parentheses
|
||||
|
||||
#pragma warning(disable:4100) // unreferenced
|
||||
#pragma warning(disable:6101) // uninitialized
|
||||
#pragma warning(disable:6386) // buffer overrun
|
||||
|
||||
#define IS_LOOPBACK(Address) ((Address.si_family == QUIC_ADDRESS_FAMILY_INET && \
|
||||
Address.Ipv4.sin_addr.S_un.S_addr == htonl(INADDR_LOOPBACK)) || \
|
||||
(Address.si_family == QUIC_ADDRESS_FAMILY_INET6 && \
|
||||
IN6_IS_ADDR_LOOPBACK(&Address.Ipv6.sin6_addr)))
|
||||
|
||||
#define DatapathType(SendData) ((CXPLAT_SEND_DATA_COMMON*)(SendData))->DatapathType
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathInitialize(
|
||||
_In_ uint32_t ClientRecvContextLength,
|
||||
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
|
||||
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
|
||||
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
|
||||
_Out_ CXPLAT_DATAPATH** NewDataPath
|
||||
)
|
||||
{
|
||||
return
|
||||
DataPathInitialize(
|
||||
ClientRecvContextLength,
|
||||
UdpCallbacks,
|
||||
TcpCallbacks,
|
||||
Config,
|
||||
NewDataPath);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDataPathUninitialize(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
)
|
||||
{
|
||||
DataPathUninitialize(Datapath);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDataPathUpdateConfig(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ QUIC_EXECUTION_CONFIG* Config
|
||||
)
|
||||
{
|
||||
DataPathUpdateConfig(Datapath, Config);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
uint32_t
|
||||
CxPlatDataPathGetSupportedFeatures(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
)
|
||||
{
|
||||
return DataPathGetSupportedFeatures(Datapath);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
CxPlatDataPathIsPaddingPreferred(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(SendData);
|
||||
return DataPathIsPaddingPreferred(Datapath);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
_Success_(QUIC_SUCCEEDED(return))
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathGetLocalAddresses(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_Outptr_ _At_(*Addresses, __drv_allocatesMem(Mem))
|
||||
CXPLAT_ADAPTER_ADDRESS** Addresses,
|
||||
_Out_ uint32_t* AddressesCount
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
*Addresses = NULL;
|
||||
*AddressesCount = 0;
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathGetGatewayAddresses(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_Outptr_ _At_(*GatewayAddresses, __drv_allocatesMem(Mem))
|
||||
QUIC_ADDR** GatewayAddresses,
|
||||
_Out_ uint32_t* GatewayAddressesCount
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
*GatewayAddresses = NULL;
|
||||
*GatewayAddressesCount = 0;
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// private func
|
||||
void
|
||||
CxPlatDataPathPopulateTargetAddress(
|
||||
_In_ QUIC_ADDRESS_FAMILY Family,
|
||||
_In_ ADDRINFO* AddrInfo,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
struct sockaddr_in6* SockAddrIn6 = NULL;
|
||||
struct sockaddr_in* SockAddrIn = NULL;
|
||||
|
||||
CxPlatZeroMemory(Address, sizeof(QUIC_ADDR));
|
||||
|
||||
if (AddrInfo->ai_addr->sa_family == AF_INET6) {
|
||||
CXPLAT_DBG_ASSERT(sizeof(struct sockaddr_in6) == AddrInfo->ai_addrlen);
|
||||
|
||||
//
|
||||
// Is this a mapped ipv4 one?
|
||||
//
|
||||
|
||||
SockAddrIn6 = (struct sockaddr_in6*)AddrInfo->ai_addr;
|
||||
|
||||
if (Family == QUIC_ADDRESS_FAMILY_UNSPEC && IN6_IS_ADDR_V4MAPPED(&SockAddrIn6->sin6_addr)) {
|
||||
SockAddrIn = &Address->Ipv4;
|
||||
|
||||
//
|
||||
// Get the ipv4 address from the mapped address.
|
||||
//
|
||||
|
||||
SockAddrIn->sin_family = QUIC_ADDRESS_FAMILY_INET;
|
||||
memcpy(&SockAddrIn->sin_addr.s_addr, &SockAddrIn6->sin6_addr.s6_addr[12], 4);
|
||||
SockAddrIn->sin_port = SockAddrIn6->sin6_port;
|
||||
|
||||
return;
|
||||
}
|
||||
Address->Ipv6 = *SockAddrIn6;
|
||||
Address->Ipv6.sin6_family = QUIC_ADDRESS_FAMILY_INET6;
|
||||
return;
|
||||
}
|
||||
|
||||
if (AddrInfo->ai_addr->sa_family == AF_INET) {
|
||||
CXPLAT_DBG_ASSERT(sizeof(struct sockaddr_in) == AddrInfo->ai_addrlen);
|
||||
SockAddrIn = (struct sockaddr_in*)AddrInfo->ai_addr;
|
||||
Address->Ipv4 = *SockAddrIn;
|
||||
Address->Ipv4.sin_family = QUIC_ADDRESS_FAMILY_INET;
|
||||
return;
|
||||
}
|
||||
|
||||
CXPLAT_FRE_ASSERT(FALSE);
|
||||
}
|
||||
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathResolveAddress(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_z_ const char* HostName,
|
||||
_Inout_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
|
||||
ADDRINFO Hints = {0};
|
||||
ADDRINFO* AddrInfo = NULL;
|
||||
int Result = 0;
|
||||
|
||||
//
|
||||
// Prepopulate hint with input family. It might be unspecified.
|
||||
//
|
||||
Hints.ai_family = Address->Ip.sa_family;
|
||||
if (Hints.ai_family == QUIC_ADDRESS_FAMILY_INET6) {
|
||||
Hints.ai_family = AF_INET6;
|
||||
}
|
||||
|
||||
//
|
||||
// Try numeric name first.
|
||||
//
|
||||
Hints.ai_flags = AI_NUMERICHOST;
|
||||
Result = getaddrinfo(HostName, NULL, &Hints, &AddrInfo);
|
||||
if (Result == 0) {
|
||||
CxPlatDataPathPopulateTargetAddress(Hints.ai_family, AddrInfo, Address);
|
||||
freeaddrinfo(AddrInfo);
|
||||
AddrInfo = NULL;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Try canonical host name.
|
||||
//
|
||||
Hints.ai_flags = AI_CANONNAME;
|
||||
Result = getaddrinfo(HostName, NULL, &Hints, &AddrInfo);
|
||||
if (Result == 0) {
|
||||
CxPlatDataPathPopulateTargetAddress(Hints.ai_family, AddrInfo, Address);
|
||||
freeaddrinfo(AddrInfo);
|
||||
AddrInfo = NULL;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
QuicTraceEvent(
|
||||
LibraryErrorStatus,
|
||||
"[ lib] ERROR, %u, %s.",
|
||||
(uint32_t)Result,
|
||||
"Resolving hostname to IP");
|
||||
QuicTraceLogError(
|
||||
DatapathResolveHostNameFailed,
|
||||
"[%p] Couldn't resolve hostname '%s' to an IP address",
|
||||
Datapath,
|
||||
HostName);
|
||||
Status = (QUIC_STATUS)Result;
|
||||
|
||||
Exit:
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateUdp(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ const CXPLAT_UDP_CONFIG* Config,
|
||||
_Out_ CXPLAT_SOCKET** NewSocket
|
||||
)
|
||||
{
|
||||
return SocketCreateUdp(
|
||||
Datapath,
|
||||
Config,
|
||||
NewSocket);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateTcp(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_opt_ const QUIC_ADDR* LocalAddress,
|
||||
_In_ const QUIC_ADDR* RemoteAddress,
|
||||
_In_opt_ void* CallbackContext,
|
||||
_Out_ CXPLAT_SOCKET** NewSocket
|
||||
)
|
||||
{
|
||||
return SocketCreateTcp(
|
||||
Datapath,
|
||||
LocalAddress,
|
||||
RemoteAddress,
|
||||
CallbackContext,
|
||||
NewSocket);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateTcpListener(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_opt_ const QUIC_ADDR* LocalAddress,
|
||||
_In_opt_ void* RecvCallbackContext,
|
||||
_Out_ CXPLAT_SOCKET** NewSocket
|
||||
)
|
||||
{
|
||||
return SocketCreateTcpListener(
|
||||
Datapath,
|
||||
LocalAddress,
|
||||
RecvCallbackContext,
|
||||
NewSocket);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatSocketDelete(
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
)
|
||||
{
|
||||
SocketDelete(Socket);
|
||||
}
|
||||
|
||||
QUIC_STATUS
|
||||
CxPlatSocketUpdateQeo(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_reads_(OffloadCount)
|
||||
const CXPLAT_QEO_CONNECTION* Offloads,
|
||||
_In_ uint32_t OffloadCount
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Socket);
|
||||
UNREFERENCED_PARAMETER(Offloads);
|
||||
UNREFERENCED_PARAMETER(OffloadCount);
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
uint16_t
|
||||
CxPlatSocketGetLocalMtu(
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Socket != NULL);
|
||||
return Socket->Mtu;
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatSocketGetLocalAddress(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Socket != NULL);
|
||||
*Address = Socket->LocalAddress;
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatSocketGetRemoteAddress(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Socket != NULL);
|
||||
*Address = Socket->RemoteAddress;
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatRecvDataReturn(
|
||||
_In_opt_ CXPLAT_RECV_DATA* RecvDataChain
|
||||
)
|
||||
{
|
||||
RecvDataReturn(RecvDataChain);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
CXPLAT_SEND_DATA*
|
||||
CxPlatSendDataAlloc(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Inout_ CXPLAT_SEND_CONFIG* Config
|
||||
)
|
||||
{
|
||||
return SendDataAlloc(Socket, Config);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSendDataFree(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
SendDataFree(SendData);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
QUIC_BUFFER*
|
||||
CxPlatSendDataAllocBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ uint16_t MaxBufferLength
|
||||
)
|
||||
{
|
||||
return SendDataAllocBuffer(SendData, MaxBufferLength);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSendDataFreeBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ QUIC_BUFFER* Buffer
|
||||
)
|
||||
{
|
||||
SendDataFreeBuffer(SendData, Buffer);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
CxPlatSendDataIsFull(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
return SendDataIsFull(SendData);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketSend(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ const CXPLAT_ROUTE* Route,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
return SocketSend(Socket, Route, SendData);
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatDataPathProcessCqe(
|
||||
_In_ CXPLAT_CQE* Cqe
|
||||
)
|
||||
{
|
||||
DataPathProcessCqe(Cqe);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
QuicCopyRouteInfo(
|
||||
_Inout_ CXPLAT_ROUTE* DstRoute,
|
||||
_In_ CXPLAT_ROUTE* SrcRoute
|
||||
)
|
||||
{
|
||||
*DstRoute = *SrcRoute;
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatResolveRouteComplete(
|
||||
_In_ void* Context,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_reads_bytes_(6) const uint8_t* PhysicalAddress,
|
||||
_In_ uint8_t PathId
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Context);
|
||||
UNREFERENCED_PARAMETER(Route);
|
||||
UNREFERENCED_PARAMETER(PhysicalAddress);
|
||||
UNREFERENCED_PARAMETER(PathId);
|
||||
}
|
||||
|
||||
//
|
||||
// Tries to resolve route and neighbor for the given destination address.
|
||||
//
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatResolveRoute(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_ uint8_t PathId,
|
||||
_In_ void* Context,
|
||||
_In_ CXPLAT_ROUTE_RESOLUTION_CALLBACK_HANDLER Callback
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Socket);
|
||||
UNREFERENCED_PARAMETER(PathId);
|
||||
UNREFERENCED_PARAMETER(Context);
|
||||
UNREFERENCED_PARAMETER(Callback);
|
||||
Route->State = RouteResolved;
|
||||
return QUIC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatUpdateRoute(
|
||||
_Inout_ CXPLAT_ROUTE* DstRoute,
|
||||
_In_ CXPLAT_ROUTE* SrcRoute
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(DstRoute);
|
||||
UNREFERENCED_PARAMETER(SrcRoute);
|
||||
}
|
||||
|
|
@ -17,7 +17,6 @@ typedef struct CXPLAT_SOCKET_POOL {
|
|||
|
||||
} CXPLAT_SOCKET_POOL;
|
||||
|
||||
typedef struct CXPLAT_DATAPATH CXPLAT_DATAPATH;
|
||||
|
||||
//
|
||||
// A worker thread for draining queued route resolution operations.
|
||||
|
@ -43,9 +42,8 @@ typedef struct QUIC_CACHEALIGN CXPLAT_ROUTE_RESOLUTION_WORKER {
|
|||
CXPLAT_LIST_ENTRY Operations;
|
||||
} CXPLAT_ROUTE_RESOLUTION_WORKER;
|
||||
|
||||
typedef struct CXPLAT_DATAPATH {
|
||||
|
||||
CXPLAT_UDP_DATAPATH_CALLBACKS UdpHandlers;
|
||||
typedef struct CXPLAT_DATAPATH_RAW {
|
||||
const CXPLAT_DATAPATH *ParentDataPath;
|
||||
|
||||
CXPLAT_SOCKET_POOL SocketPool;
|
||||
|
||||
|
@ -59,7 +57,7 @@ typedef struct CXPLAT_DATAPATH {
|
|||
#endif
|
||||
BOOLEAN UseTcp;
|
||||
|
||||
} CXPLAT_DATAPATH;
|
||||
} CXPLAT_DATAPATH_RAW;
|
||||
|
||||
#define ETH_MAC_ADDR_LEN 6
|
||||
|
||||
|
@ -81,33 +79,19 @@ typedef struct CXPLAT_INTERFACE {
|
|||
} CXPLAT_INTERFACE;
|
||||
|
||||
typedef struct CXPLAT_SEND_DATA {
|
||||
|
||||
//
|
||||
// The type of ECN markings needed for send.
|
||||
//
|
||||
CXPLAT_ECN_TYPE ECN;
|
||||
CXPLAT_SEND_DATA_COMMON;
|
||||
|
||||
QUIC_BUFFER Buffer;
|
||||
|
||||
} CXPLAT_SEND_DATA;
|
||||
|
||||
//
|
||||
// Queries the raw datapath stack for the total size needed to allocate the
|
||||
// datapath structure.
|
||||
//
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
size_t
|
||||
CxPlatDpRawGetDatapathSize(
|
||||
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
|
||||
);
|
||||
|
||||
//
|
||||
// Initializes the raw datapath stack.
|
||||
//
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatDpRawInitialize(
|
||||
_Inout_ CXPLAT_DATAPATH* Datapath,
|
||||
_Inout_ CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_ uint32_t ClientRecvContextLength,
|
||||
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
|
||||
);
|
||||
|
@ -118,7 +102,7 @@ CxPlatDpRawInitialize(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDpRawUninitialize(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
);
|
||||
|
||||
//
|
||||
|
@ -127,7 +111,7 @@ CxPlatDpRawUninitialize(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDataPathUninitializeComplete(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
);
|
||||
|
||||
//
|
||||
|
@ -136,7 +120,7 @@ CxPlatDataPathUninitializeComplete(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDpRawUpdateConfig(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_ QUIC_EXECUTION_CONFIG* Config
|
||||
);
|
||||
|
||||
|
@ -147,7 +131,7 @@ CxPlatDpRawUpdateConfig(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDpRawPlumbRulesOnSocket(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ BOOLEAN IsCreated
|
||||
);
|
||||
|
||||
|
@ -206,7 +190,7 @@ CxPlatDpRawParseEthernet(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatDpRawRxEthernet(
|
||||
_In_ const CXPLAT_DATAPATH* Datapath,
|
||||
_In_ const CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_reads_(PacketCount)
|
||||
CXPLAT_RECV_DATA** Packets,
|
||||
_In_ uint16_t PacketCount
|
||||
|
@ -227,7 +211,7 @@ CxPlatDpRawRxFree(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
CXPLAT_SEND_DATA*
|
||||
CxPlatDpRawTxAlloc(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_Inout_ CXPLAT_SEND_CONFIG* Config
|
||||
);
|
||||
|
||||
|
@ -253,27 +237,24 @@ CxPlatDpRawTxEnqueue(
|
|||
// Raw Socket Interface
|
||||
//
|
||||
|
||||
typedef struct CXPLAT_SOCKET {
|
||||
typedef struct CXPLAT_SOCKET_RAW {
|
||||
|
||||
CXPLAT_HASHTABLE_ENTRY Entry;
|
||||
CXPLAT_RUNDOWN_REF Rundown;
|
||||
CXPLAT_DATAPATH* Datapath;
|
||||
CXPLAT_DATAPATH_RAW* RawDatapath;
|
||||
SOCKET AuxSocket;
|
||||
void* CallbackContext;
|
||||
QUIC_ADDR LocalAddress;
|
||||
QUIC_ADDR RemoteAddress;
|
||||
BOOLEAN Wildcard; // Using a wildcard local address. Optimization
|
||||
// to avoid always reading LocalAddress.
|
||||
BOOLEAN Connected; // Bound to a remote address
|
||||
uint8_t CibirIdLength; // CIBIR ID length. Value of 0 indicates CIBIR isn't used
|
||||
uint8_t CibirIdOffsetSrc; // CIBIR ID offset in source CID
|
||||
uint8_t CibirIdOffsetDst; // CIBIR ID offset in destination CID
|
||||
uint8_t CibirId[6]; // CIBIR ID data
|
||||
BOOLEAN UseTcp; // Quic over TCP
|
||||
|
||||
CXPLAT_SEND_DATA* PausedTcpSend; // Paused TCP send data *before* framing
|
||||
CXPLAT_SEND_DATA* CachedRstSend; // Cached TCP RST send data *after* framing
|
||||
} CXPLAT_SOCKET;
|
||||
|
||||
CXPLAT_SOCKET;
|
||||
} CXPLAT_SOCKET_RAW;
|
||||
|
||||
BOOLEAN
|
||||
CxPlatSockPoolInitialize(
|
||||
|
@ -293,7 +274,7 @@ CxPlatSockPoolUninitialize(
|
|||
inline
|
||||
BOOLEAN
|
||||
CxPlatSocketCompare(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ const QUIC_ADDR* LocalAddress,
|
||||
_In_ const QUIC_ADDR* RemoteAddress
|
||||
)
|
||||
|
@ -315,7 +296,7 @@ CxPlatSocketCompare(
|
|||
//
|
||||
// Finds a socket to deliver received packets with the given addresses.
|
||||
//
|
||||
CXPLAT_SOCKET*
|
||||
CXPLAT_SOCKET_RAW*
|
||||
CxPlatGetSocket(
|
||||
_In_ const CXPLAT_SOCKET_POOL* Pool,
|
||||
_In_ const QUIC_ADDR* LocalAddress,
|
||||
|
@ -325,13 +306,13 @@ CxPlatGetSocket(
|
|||
QUIC_STATUS
|
||||
CxPlatTryAddSocket(
|
||||
_In_ CXPLAT_SOCKET_POOL* Pool,
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
);
|
||||
|
||||
void
|
||||
CxPlatRemoveSocket(
|
||||
_In_ CXPLAT_SOCKET_POOL* Pool,
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
);
|
||||
|
||||
//
|
||||
|
@ -351,28 +332,28 @@ typedef enum PACKET_TYPE {
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatDpRawSocketAckSyn(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ CXPLAT_RECV_DATA* Packet
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatDpRawSocketSyn(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ const CXPLAT_ROUTE* Route
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatDpRawSocketAckFin(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ CXPLAT_RECV_DATA* Packet
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatFramingWriteHeaders(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ const CXPLAT_ROUTE* Route,
|
||||
_Inout_ QUIC_BUFFER* Buffer,
|
||||
_In_ CXPLAT_ECN_TYPE ECN,
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
Licensed under the MIT License.
|
||||
|
||||
Abstract:
|
||||
|
||||
QUIC Datapath Implementation (User Mode)
|
||||
|
||||
--*/
|
||||
|
||||
#include "datapath_raw.h"
|
||||
#include "platform_internal.h"
|
||||
|
||||
uint32_t
|
||||
CxPlatGetRawSocketSize(void) {
|
||||
return sizeof(CXPLAT_SOCKET_RAW);
|
||||
}
|
||||
|
||||
CXPLAT_SOCKET*
|
||||
CxPlatRawToSocket(_In_ CXPLAT_SOCKET_RAW* Socket) {
|
||||
return (CXPLAT_SOCKET*)((unsigned char*)Socket + sizeof(CXPLAT_SOCKET_RAW) - sizeof(CXPLAT_SOCKET));
|
||||
}
|
||||
|
||||
CXPLAT_SOCKET_RAW*
|
||||
CxPlatSocketToRaw(_In_ CXPLAT_SOCKET* Socket) {
|
||||
return (CXPLAT_SOCKET_RAW*)((unsigned char*)Socket - sizeof(CXPLAT_SOCKET_RAW) + sizeof(CXPLAT_SOCKET));
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
RawSocketCreateUdp(
|
||||
_In_ CXPLAT_DATAPATH_RAW* DataPath,
|
||||
_In_ const CXPLAT_UDP_CONFIG* Config,
|
||||
_Inout_ CXPLAT_SOCKET_RAW* NewSocket
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(DataPath);
|
||||
UNREFERENCED_PARAMETER(Config);
|
||||
UNREFERENCED_PARAMETER(NewSocket);
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
RawSocketDelete(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Socket);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
RawDataPathInitialize(
|
||||
_In_ uint32_t ClientRecvContextLength,
|
||||
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
|
||||
_In_opt_ const CXPLAT_DATAPATH* ParentDataPath,
|
||||
_Out_ CXPLAT_DATAPATH_RAW** DataPath
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ClientRecvContextLength);
|
||||
UNREFERENCED_PARAMETER(Config);
|
||||
UNREFERENCED_PARAMETER(ParentDataPath);
|
||||
UNREFERENCED_PARAMETER(DataPath);
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
RawDataPathUninitialize(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
RawDataPathUpdateConfig(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_ QUIC_EXECUTION_CONFIG* Config
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
UNREFERENCED_PARAMETER(Config);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
uint32_t
|
||||
RawDataPathGetSupportedFeatures(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
RawDataPathIsPaddingPreferred(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
RawSocketUpdateQeo(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_reads_(OffloadCount)
|
||||
const CXPLAT_QEO_CONNECTION* Offloads,
|
||||
_In_ uint32_t OffloadCount
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Socket);
|
||||
UNREFERENCED_PARAMETER(Offloads);
|
||||
UNREFERENCED_PARAMETER(OffloadCount);
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
UINT16
|
||||
RawSocketGetLocalMtu(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Socket);
|
||||
return 1500;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
RawRecvDataReturn(
|
||||
_In_ CXPLAT_RECV_DATA* RecvDataChain
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(RecvDataChain);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
CXPLAT_SEND_DATA*
|
||||
RawSendDataAlloc(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_Inout_ CXPLAT_SEND_CONFIG* Config
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Socket);
|
||||
UNREFERENCED_PARAMETER(Config);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
RawSendDataFree(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(SendData);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
QUIC_BUFFER*
|
||||
RawSendDataAllocBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ uint16_t MaxBufferLength
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(SendData);
|
||||
UNREFERENCED_PARAMETER(MaxBufferLength);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
RawSendDataFreeBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ QUIC_BUFFER* Buffer
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(SendData);
|
||||
UNREFERENCED_PARAMETER(Buffer);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
RawSendDataIsFull(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(SendData);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
QUIC_STATUS
|
||||
RawSocketSend(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ const CXPLAT_ROUTE* Route,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Socket);
|
||||
UNREFERENCED_PARAMETER(Route);
|
||||
UNREFERENCED_PARAMETER(SendData);
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
void
|
||||
RawResolveRouteComplete(
|
||||
_In_ void* Context,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_reads_bytes_(6) const uint8_t* PhysicalAddress,
|
||||
_In_ uint8_t PathId
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Context);
|
||||
UNREFERENCED_PARAMETER(Route);
|
||||
UNREFERENCED_PARAMETER(PhysicalAddress);
|
||||
UNREFERENCED_PARAMETER(PathId);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
RawResolveRoute(
|
||||
_In_ CXPLAT_SOCKET_RAW* Sock,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_ uint8_t PathId,
|
||||
_In_ void* Context,
|
||||
_In_ CXPLAT_ROUTE_RESOLUTION_CALLBACK_HANDLER Callback
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Sock);
|
||||
UNREFERENCED_PARAMETER(Route);
|
||||
UNREFERENCED_PARAMETER(PathId);
|
||||
UNREFERENCED_PARAMETER(Context);
|
||||
UNREFERENCED_PARAMETER(Callback);
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
void
|
||||
RawDataPathProcessCqe(
|
||||
_In_ CXPLAT_CQE* Cqe
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Cqe);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
RawUpdateRoute(
|
||||
_Inout_ CXPLAT_ROUTE* DstRoute,
|
||||
_In_ CXPLAT_ROUTE* SrcRoute
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(DstRoute);
|
||||
UNREFERENCED_PARAMETER(SrcRoute);
|
||||
}
|
|
@ -45,7 +45,7 @@ CxPlatDataPathRouteWorkerUninitialize(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathRouteWorkerInitialize(
|
||||
_Inout_ CXPLAT_DATAPATH* DataPath
|
||||
_Inout_ CXPLAT_DATAPATH_RAW* DataPath
|
||||
)
|
||||
{
|
||||
QUIC_STATUS Status;
|
||||
|
@ -104,99 +104,24 @@ Error:
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathInitialize(
|
||||
RawDataPathInitialize(
|
||||
_In_ uint32_t ClientRecvContextLength,
|
||||
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
|
||||
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
|
||||
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
|
||||
_Out_ CXPLAT_DATAPATH** NewDataPath
|
||||
_In_opt_ const CXPLAT_DATAPATH* ParentDataPath,
|
||||
_Out_ CXPLAT_DATAPATH_RAW** NewDataPath
|
||||
)
|
||||
{
|
||||
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
|
||||
const size_t DatapathSize = CxPlatDpRawGetDatapathSize(Config);
|
||||
BOOLEAN DpRawInitialized = FALSE;
|
||||
BOOLEAN SockPoolInitialized = FALSE;
|
||||
CXPLAT_FRE_ASSERT(DatapathSize > sizeof(CXPLAT_DATAPATH));
|
||||
|
||||
UNREFERENCED_PARAMETER(TcpCallbacks);
|
||||
|
||||
if (NewDataPath == NULL) {
|
||||
return QUIC_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (UdpCallbacks != NULL) {
|
||||
if (UdpCallbacks->Receive == NULL || UdpCallbacks->Unreachable == NULL) {
|
||||
return QUIC_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CxPlatWorkersLazyStart(Config)) {
|
||||
return QUIC_STATUS_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
CXPLAT_DATAPATH* DataPath = CXPLAT_ALLOC_PAGED(DatapathSize, QUIC_POOL_DATAPATH);
|
||||
if (DataPath == NULL) {
|
||||
QuicTraceEvent(
|
||||
AllocFailure,
|
||||
"Allocation of '%s' failed. (%llu bytes)",
|
||||
"CXPLAT_DATAPATH",
|
||||
DatapathSize);
|
||||
return QUIC_STATUS_OUT_OF_MEMORY;
|
||||
}
|
||||
CxPlatZeroMemory(DataPath, DatapathSize);
|
||||
CXPLAT_FRE_ASSERT(CxPlatRundownAcquire(&CxPlatWorkerRundown));
|
||||
|
||||
if (UdpCallbacks) {
|
||||
DataPath->UdpHandlers = *UdpCallbacks;
|
||||
}
|
||||
|
||||
if (Config && (Config->Flags & QUIC_EXECUTION_CONFIG_FLAG_QTIP)) {
|
||||
DataPath->UseTcp = TRUE;
|
||||
}
|
||||
|
||||
if (!CxPlatSockPoolInitialize(&DataPath->SocketPool)) {
|
||||
Status = QUIC_STATUS_OUT_OF_MEMORY;
|
||||
goto Error;
|
||||
}
|
||||
SockPoolInitialized = TRUE;
|
||||
|
||||
Status = CxPlatDpRawInitialize(DataPath, ClientRecvContextLength, Config);
|
||||
if (QUIC_FAILED(Status)) {
|
||||
goto Error;
|
||||
}
|
||||
DpRawInitialized = TRUE;
|
||||
|
||||
Status = CxPlatDataPathRouteWorkerInitialize(DataPath);
|
||||
if (QUIC_FAILED(Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
*NewDataPath = DataPath;
|
||||
DataPath = NULL;
|
||||
|
||||
Error:
|
||||
|
||||
if (DataPath != NULL) {
|
||||
#if DEBUG
|
||||
DataPath->Uninitialized = TRUE;
|
||||
#endif
|
||||
if (DpRawInitialized) {
|
||||
CxPlatDpRawUninitialize(DataPath);
|
||||
} else {
|
||||
if (SockPoolInitialized) {
|
||||
CxPlatSockPoolUninitialize(&DataPath->SocketPool);
|
||||
}
|
||||
CXPLAT_FREE(DataPath, QUIC_POOL_DATAPATH);
|
||||
CxPlatRundownRelease(&CxPlatWorkerRundown);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
UNREFERENCED_PARAMETER(ClientRecvContextLength);
|
||||
UNREFERENCED_PARAMETER(Config);
|
||||
UNREFERENCED_PARAMETER(ParentDataPath);
|
||||
UNREFERENCED_PARAMETER(NewDataPath);
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDataPathUninitialize(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
RawDataPathUninitialize(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
)
|
||||
{
|
||||
if (Datapath != NULL) {
|
||||
|
@ -213,7 +138,7 @@ CxPlatDataPathUninitialize(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDataPathUninitializeComplete(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
)
|
||||
{
|
||||
#if DEBUG
|
||||
|
@ -228,8 +153,8 @@ CxPlatDataPathUninitializeComplete(
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDataPathUpdateConfig(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
RawDataPathUpdateConfig(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_ QUIC_EXECUTION_CONFIG* Config
|
||||
)
|
||||
{
|
||||
|
@ -239,8 +164,8 @@ CxPlatDataPathUpdateConfig(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
uint32_t
|
||||
CxPlatDataPathGetSupportedFeatures(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
RawDataPathGetSupportedFeatures(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
|
@ -249,7 +174,7 @@ CxPlatDataPathGetSupportedFeatures(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
CxPlatDataPathIsPaddingPreferred(
|
||||
RawDataPathIsPaddingPreferred(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
)
|
||||
{
|
||||
|
@ -258,208 +183,32 @@ CxPlatDataPathIsPaddingPreferred(
|
|||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
_Success_(QUIC_SUCCEEDED(return))
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathGetLocalAddresses(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_Outptr_ _At_(*Addresses, __drv_allocatesMem(Mem))
|
||||
CXPLAT_ADAPTER_ADDRESS** Addresses,
|
||||
_Out_ uint32_t* AddressesCount
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
UNREFERENCED_PARAMETER(Addresses);
|
||||
UNREFERENCED_PARAMETER(AddressesCount);
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
_Success_(QUIC_SUCCEEDED(return))
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathGetGatewayAddresses(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_Outptr_ _At_(*GatewayAddresses, __drv_allocatesMem(Mem))
|
||||
QUIC_ADDR** GatewayAddresses,
|
||||
_Out_ uint32_t* GatewayAddressesCount
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
UNREFERENCED_PARAMETER(GatewayAddresses);
|
||||
UNREFERENCED_PARAMETER(GatewayAddressesCount);
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatDataPathPopulateTargetAddress(
|
||||
_In_ QUIC_ADDRESS_FAMILY Family,
|
||||
_In_ ADDRINFO* AddrInfo,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Family);
|
||||
UNREFERENCED_PARAMETER(AddrInfo);
|
||||
UNREFERENCED_PARAMETER(Address);
|
||||
}
|
||||
|
||||
// ->CxPlat
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathResolveAddress(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_z_ const char* HostName,
|
||||
_Inout_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
UNREFERENCED_PARAMETER(HostName);
|
||||
UNREFERENCED_PARAMETER(Address);
|
||||
QUIC_STATUS Status = QUIC_STATUS_NOT_SUPPORTED;
|
||||
return Status;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateUdp(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
RawSocketCreateUdp(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_ const CXPLAT_UDP_CONFIG* Config,
|
||||
_Out_ CXPLAT_SOCKET** NewSocket
|
||||
)
|
||||
{
|
||||
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
|
||||
|
||||
*NewSocket = CXPLAT_ALLOC_PAGED(sizeof(CXPLAT_SOCKET), QUIC_POOL_SOCKET);
|
||||
if (*NewSocket == NULL) {
|
||||
QuicTraceEvent(
|
||||
AllocFailure,
|
||||
"Allocation of '%s' failed. (%llu bytes)",
|
||||
"CXPLAT_SOCKET",
|
||||
sizeof(CXPLAT_SOCKET));
|
||||
Status = QUIC_STATUS_OUT_OF_MEMORY;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
QuicTraceEvent(
|
||||
DatapathCreated,
|
||||
"[data][%p] Created, local=%!ADDR!, remote=%!ADDR!",
|
||||
*NewSocket,
|
||||
CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress),
|
||||
CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress));
|
||||
|
||||
CxPlatZeroMemory(*NewSocket, sizeof(CXPLAT_SOCKET));
|
||||
CxPlatRundownInitialize(&(*NewSocket)->Rundown);
|
||||
(*NewSocket)->Datapath = Datapath;
|
||||
(*NewSocket)->CallbackContext = Config->CallbackContext;
|
||||
(*NewSocket)->CibirIdLength = Config->CibirIdLength;
|
||||
(*NewSocket)->CibirIdOffsetSrc = Config->CibirIdOffsetSrc;
|
||||
(*NewSocket)->CibirIdOffsetDst = Config->CibirIdOffsetDst;
|
||||
(*NewSocket)->UseTcp = Datapath->UseTcp;
|
||||
if (Config->CibirIdLength) {
|
||||
memcpy((*NewSocket)->CibirId, Config->CibirId, Config->CibirIdLength);
|
||||
}
|
||||
|
||||
if (Config->RemoteAddress) {
|
||||
CXPLAT_FRE_ASSERT(!QuicAddrIsWildCard(Config->RemoteAddress)); // No wildcard remote addresses allowed.
|
||||
(*NewSocket)->Connected = TRUE;
|
||||
(*NewSocket)->RemoteAddress = *Config->RemoteAddress;
|
||||
}
|
||||
|
||||
if (Config->LocalAddress) {
|
||||
(*NewSocket)->LocalAddress = *Config->LocalAddress;
|
||||
if (QuicAddrIsWildCard(Config->LocalAddress)) {
|
||||
if (!(*NewSocket)->Connected) {
|
||||
(*NewSocket)->Wildcard = TRUE;
|
||||
}
|
||||
} else {
|
||||
CXPLAT_FRE_ASSERT((*NewSocket)->Connected); // Assumes only connected sockets fully specify local address
|
||||
}
|
||||
} else {
|
||||
QuicAddrSetFamily(&(*NewSocket)->LocalAddress, QUIC_ADDRESS_FAMILY_INET6);
|
||||
if (!(*NewSocket)->Connected) {
|
||||
(*NewSocket)->Wildcard = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
CXPLAT_FRE_ASSERT((*NewSocket)->Wildcard ^ (*NewSocket)->Connected); // Assumes either a pure wildcard listener or a
|
||||
// connected socket; not both.
|
||||
|
||||
Status = CxPlatTryAddSocket(&Datapath->SocketPool, *NewSocket);
|
||||
if (QUIC_FAILED(Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
CxPlatDpRawPlumbRulesOnSocket(*NewSocket, TRUE);
|
||||
|
||||
Error:
|
||||
|
||||
if (QUIC_FAILED(Status)) {
|
||||
if (*NewSocket != NULL) {
|
||||
CxPlatRundownUninitialize(&(*NewSocket)->Rundown);
|
||||
CXPLAT_FREE(*NewSocket, QUIC_POOL_SOCKET);
|
||||
*NewSocket = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateTcp(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_opt_ const QUIC_ADDR* LocalAddress,
|
||||
_In_ const QUIC_ADDR* RemoteAddress,
|
||||
_In_opt_ void* CallbackContext,
|
||||
_Out_ CXPLAT_SOCKET** Socket
|
||||
_Inout_ CXPLAT_SOCKET_RAW* NewSocket
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
UNREFERENCED_PARAMETER(LocalAddress);
|
||||
UNREFERENCED_PARAMETER(RemoteAddress);
|
||||
UNREFERENCED_PARAMETER(CallbackContext);
|
||||
UNREFERENCED_PARAMETER(Socket);
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateTcpListener(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_opt_ const QUIC_ADDR* LocalAddress,
|
||||
_In_opt_ void* RecvCallbackContext,
|
||||
_Out_ CXPLAT_SOCKET** NewSocket
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
UNREFERENCED_PARAMETER(LocalAddress);
|
||||
UNREFERENCED_PARAMETER(RecvCallbackContext);
|
||||
UNREFERENCED_PARAMETER(Config);
|
||||
UNREFERENCED_PARAMETER(NewSocket);
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatSocketDelete(
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
RawSocketDelete(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
)
|
||||
{
|
||||
CxPlatDpRawPlumbRulesOnSocket(Socket, FALSE);
|
||||
CxPlatRemoveSocket(&Socket->Datapath->SocketPool, Socket);
|
||||
CxPlatRundownReleaseAndWait(&Socket->Rundown);
|
||||
if (Socket->PausedTcpSend) {
|
||||
CxPlatDpRawTxFree(Socket->PausedTcpSend);
|
||||
}
|
||||
|
||||
if (Socket->CachedRstSend) {
|
||||
CxPlatDpRawTxEnqueue(Socket->CachedRstSend);
|
||||
}
|
||||
|
||||
CXPLAT_FREE(Socket, QUIC_POOL_SOCKET);
|
||||
UNREFERENCED_PARAMETER(Socket);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketUpdateQeo(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
RawSocketUpdateQeo(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_reads_(OffloadCount)
|
||||
const CXPLAT_QEO_CONNECTION* Offloads,
|
||||
_In_ uint32_t OffloadCount
|
||||
|
@ -473,48 +222,26 @@ CxPlatSocketUpdateQeo(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
uint16_t
|
||||
CxPlatSocketGetLocalMtu(
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
RawSocketGetLocalMtu(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
)
|
||||
{
|
||||
if (Socket->UseTcp) {
|
||||
return 1488; // Reserve space for TCP header.
|
||||
} else {
|
||||
return 1500;
|
||||
}
|
||||
}
|
||||
// Reserve space for TCP header.
|
||||
return Socket->UseTcp ? 1488 : 1500;
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSocketGetLocalAddress(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
*Address = Socket->LocalAddress;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSocketGetRemoteAddress(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
*Address = Socket->RemoteAddress;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatDpRawRxEthernet(
|
||||
_In_ const CXPLAT_DATAPATH* Datapath,
|
||||
_In_ const CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_reads_(PacketCount)
|
||||
CXPLAT_RECV_DATA** Packets,
|
||||
_In_ uint16_t PacketCount
|
||||
)
|
||||
{
|
||||
for (uint16_t i = 0; i < PacketCount; i++) {
|
||||
CXPLAT_SOCKET* Socket = NULL;
|
||||
CXPLAT_SOCKET_RAW* Socket = NULL;
|
||||
CXPLAT_RECV_DATA* PacketChain = Packets[i];
|
||||
CXPLAT_DBG_ASSERT(PacketChain->Next == NULL);
|
||||
|
||||
|
@ -552,7 +279,7 @@ CxPlatDpRawRxEthernet(
|
|||
CXPLAT_DBG_ASSERT(Packets[i+1]->Next == NULL);
|
||||
i++;
|
||||
}
|
||||
Datapath->UdpHandlers.Receive(Socket, Socket->CallbackContext, (CXPLAT_RECV_DATA*)PacketChain);
|
||||
Datapath->ParentDataPath->UdpHandlers.Receive(CxPlatRawToSocket(Socket), Socket->ClientContext, PacketChain);
|
||||
} else if (PacketChain->Reserved == L4_TYPE_TCP_SYN || PacketChain->Reserved == L4_TYPE_TCP_SYNACK) {
|
||||
CxPlatDpRawSocketAckSyn(Socket, PacketChain);
|
||||
CxPlatDpRawRxFree(PacketChain);
|
||||
|
@ -572,7 +299,7 @@ CxPlatDpRawRxEthernet(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatRecvDataReturn(
|
||||
RawRecvDataReturn(
|
||||
_In_opt_ CXPLAT_RECV_DATA* RecvDataChain
|
||||
)
|
||||
{
|
||||
|
@ -582,8 +309,8 @@ CxPlatRecvDataReturn(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
CXPLAT_SEND_DATA*
|
||||
CxPlatSendDataAlloc(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
RawSendDataAlloc(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_Inout_ CXPLAT_SEND_CONFIG* Config
|
||||
)
|
||||
{
|
||||
|
@ -593,7 +320,7 @@ CxPlatSendDataAlloc(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
QUIC_BUFFER*
|
||||
CxPlatSendDataAllocBuffer(
|
||||
RawSendDataAllocBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ uint16_t MaxBufferLength
|
||||
)
|
||||
|
@ -604,7 +331,7 @@ CxPlatSendDataAllocBuffer(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSendDataFree(
|
||||
RawSendDataFree(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
|
@ -613,7 +340,7 @@ CxPlatSendDataFree(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSendDataFreeBuffer(
|
||||
RawSendDataFreeBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ QUIC_BUFFER* Buffer
|
||||
)
|
||||
|
@ -625,7 +352,7 @@ CxPlatSendDataFreeBuffer(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
CxPlatSendDataIsFull(
|
||||
RawSendDataIsFull(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
|
@ -637,8 +364,8 @@ CxPlatSendDataIsFull(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketSend(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
RawSocketSend(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ const CXPLAT_ROUTE* Route,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
|
|
|
@ -17,20 +17,36 @@ Abstract:
|
|||
#pragma warning(disable:4116) // unnamed type definition in parentheses
|
||||
#pragma warning(disable:4100) // unreferenced formal parameter
|
||||
|
||||
|
||||
uint32_t
|
||||
CxPlatGetRawSocketSize(void) {
|
||||
return sizeof(CXPLAT_SOCKET_RAW);
|
||||
}
|
||||
|
||||
CXPLAT_SOCKET*
|
||||
CxPlatRawToSocket(_In_ CXPLAT_SOCKET_RAW* Socket) {
|
||||
return (CXPLAT_SOCKET*)((unsigned char*)Socket + sizeof(CXPLAT_SOCKET_RAW) - sizeof(CXPLAT_SOCKET));
|
||||
}
|
||||
|
||||
CXPLAT_SOCKET_RAW*
|
||||
CxPlatSocketToRaw(_In_ CXPLAT_SOCKET* Socket) {
|
||||
return (CXPLAT_SOCKET_RAW*)((unsigned char*)Socket - sizeof(CXPLAT_SOCKET_RAW) + sizeof(CXPLAT_SOCKET));
|
||||
}
|
||||
|
||||
CXPLAT_SOCKET_RAW*
|
||||
CxPlatGetSocket(
|
||||
_In_ const CXPLAT_SOCKET_POOL* Pool,
|
||||
_In_ const QUIC_ADDR* LocalAddress,
|
||||
_In_ const QUIC_ADDR* RemoteAddress
|
||||
)
|
||||
{
|
||||
CXPLAT_SOCKET* Socket = NULL;
|
||||
CXPLAT_SOCKET_RAW* Socket = NULL;
|
||||
CXPLAT_HASHTABLE_LOOKUP_CONTEXT Context;
|
||||
CXPLAT_HASHTABLE_ENTRY* Entry;
|
||||
CxPlatRwLockAcquireShared(&((CXPLAT_SOCKET_POOL*)Pool)->Lock);
|
||||
Entry = CxPlatHashtableLookup(&Pool->Sockets, LocalAddress->Ipv4.sin_port, &Context);
|
||||
while (Entry != NULL) {
|
||||
CXPLAT_SOCKET* Temp = CXPLAT_CONTAINING_RECORD(Entry, CXPLAT_SOCKET, Entry);
|
||||
CXPLAT_SOCKET_RAW* Temp = CXPLAT_CONTAINING_RECORD(Entry, CXPLAT_SOCKET_RAW, Entry);
|
||||
if (CxPlatSocketCompare(Temp, LocalAddress, RemoteAddress)) {
|
||||
if (CxPlatRundownAcquire(&Temp->Rundown)) {
|
||||
Socket = Temp;
|
||||
|
@ -43,19 +59,8 @@ CxPlatGetSocket(
|
|||
return Socket;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
QuicCopyRouteInfo(
|
||||
_Inout_ CXPLAT_ROUTE* DstRoute,
|
||||
_In_ CXPLAT_ROUTE* SrcRoute
|
||||
)
|
||||
{
|
||||
CxPlatCopyMemory(DstRoute, SrcRoute, (uint8_t*)&SrcRoute->State - (uint8_t*)SrcRoute);
|
||||
CxPlatUpdateRoute(DstRoute, SrcRoute);
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatResolveRouteComplete(
|
||||
RawResolveRouteComplete(
|
||||
_In_ void* Context,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_reads_bytes_(6) const uint8_t* PhysicalAddress,
|
||||
|
@ -80,7 +85,7 @@ CxPlatResolveRouteComplete(
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatUpdateRoute(
|
||||
RawUpdateRoute(
|
||||
_Inout_ CXPLAT_ROUTE* DstRoute,
|
||||
_In_ CXPLAT_ROUTE* SrcRoute
|
||||
)
|
||||
|
@ -492,7 +497,7 @@ CxPlatFramingTransportChecksum(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatDpRawSocketAckFin(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ CXPLAT_RECV_DATA* Packet
|
||||
)
|
||||
{
|
||||
|
@ -500,7 +505,7 @@ CxPlatDpRawSocketAckFin(
|
|||
|
||||
CXPLAT_ROUTE* Route = Packet->Route;
|
||||
CXPLAT_SEND_CONFIG SendConfig = { Route, 0, CXPLAT_ECN_NON_ECT, 0 };
|
||||
CXPLAT_SEND_DATA *SendData = CxPlatSendDataAlloc(Socket, &SendConfig);
|
||||
CXPLAT_SEND_DATA *SendData = CxPlatSendDataAlloc(CxPlatRawToSocket(Socket), &SendConfig);
|
||||
if (SendData == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -531,7 +536,7 @@ CxPlatDpRawSocketAckFin(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatDpRawSocketAckSyn(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ CXPLAT_RECV_DATA* Packet
|
||||
)
|
||||
{
|
||||
|
@ -539,7 +544,7 @@ CxPlatDpRawSocketAckSyn(
|
|||
|
||||
CXPLAT_ROUTE* Route = Packet->Route;
|
||||
CXPLAT_SEND_CONFIG SendConfig = { Route, 0, CXPLAT_ECN_NON_ECT, 0 };
|
||||
CXPLAT_SEND_DATA *SendData = CxPlatSendDataAlloc(Socket, &SendConfig);
|
||||
CXPLAT_SEND_DATA *SendData = CxPlatSendDataAlloc(CxPlatRawToSocket(Socket), &SendConfig);
|
||||
if (SendData == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -588,7 +593,7 @@ CxPlatDpRawSocketAckSyn(
|
|||
TH_ACK);
|
||||
CxPlatDpRawTxEnqueue(SendData);
|
||||
|
||||
SendData = CxPlatSendDataAlloc(Socket, &SendConfig);
|
||||
SendData = CxPlatSendDataAlloc(CxPlatRawToSocket(Socket), &SendConfig);
|
||||
if (SendData == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -616,14 +621,13 @@ CxPlatDpRawSocketAckSyn(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatDpRawSocketSyn(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ const CXPLAT_ROUTE* Route
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Socket->UseTcp);
|
||||
|
||||
CXPLAT_SEND_CONFIG SendConfig = { (CXPLAT_ROUTE*)Route, 0, CXPLAT_ECN_NON_ECT, 0 };
|
||||
CXPLAT_SEND_DATA *SendData = CxPlatSendDataAlloc(Socket, &SendConfig);
|
||||
CXPLAT_SEND_DATA *SendData = CxPlatSendDataAlloc(CxPlatRawToSocket(Socket), &SendConfig);
|
||||
if (SendData == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -650,7 +654,7 @@ CxPlatDpRawSocketSyn(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatFramingWriteHeaders(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ const CXPLAT_ROUTE* Route,
|
||||
_Inout_ QUIC_BUFFER* Buffer,
|
||||
_In_ CXPLAT_ECN_TYPE ECN,
|
||||
|
|
|
@ -45,7 +45,7 @@ CxPlatSockPoolUninitialize(
|
|||
void
|
||||
CxPlatRemoveSocket(
|
||||
_In_ CXPLAT_SOCKET_POOL* Pool,
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Pool);
|
||||
|
@ -54,8 +54,8 @@ CxPlatRemoveSocket(
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatResolveRoute(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
RawResolveRoute(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_ uint8_t PathId,
|
||||
_In_ void* Context,
|
||||
|
@ -74,7 +74,7 @@ CxPlatResolveRoute(
|
|||
QUIC_STATUS
|
||||
CxPlatTryAddSocket(
|
||||
_In_ CXPLAT_SOCKET_POOL* Pool,
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Pool);
|
||||
|
|
|
@ -56,13 +56,14 @@ CxPlatSockPoolUninitialize(
|
|||
void
|
||||
CxPlatRemoveSocket(
|
||||
_In_ CXPLAT_SOCKET_POOL* Pool,
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
)
|
||||
{
|
||||
CxPlatRwLockAcquireExclusive(&Pool->Lock);
|
||||
CxPlatHashtableRemove(&Pool->Sockets, &Socket->Entry, NULL);
|
||||
|
||||
if (closesocket(Socket->AuxSocket) == SOCKET_ERROR) {
|
||||
if (Socket->AuxSocket != INVALID_SOCKET &&
|
||||
closesocket(Socket->AuxSocket) == SOCKET_ERROR) {
|
||||
int Error = SocketError();
|
||||
QuicTraceEvent(
|
||||
DatapathErrorStatus,
|
||||
|
@ -77,8 +78,8 @@ CxPlatRemoveSocket(
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatResolveRoute(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
RawResolveRoute(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_ uint8_t PathId,
|
||||
_In_ void* Context,
|
||||
|
@ -150,8 +151,8 @@ CxPlatResolveRoute(
|
|||
//
|
||||
// Find the interface that matches the route we just looked up.
|
||||
//
|
||||
CXPLAT_LIST_ENTRY* Entry = Socket->Datapath->Interfaces.Flink;
|
||||
for (; Entry != &Socket->Datapath->Interfaces; Entry = Entry->Flink) {
|
||||
CXPLAT_LIST_ENTRY* Entry = Socket->RawDatapath->Interfaces.Flink;
|
||||
for (; Entry != &Socket->RawDatapath->Interfaces; Entry = Entry->Flink) {
|
||||
CXPLAT_INTERFACE* Interface = CONTAINING_RECORD(Entry, CXPLAT_INTERFACE, Link);
|
||||
if (Interface->IfIndex == IpforwardRow.InterfaceIndex) {
|
||||
CXPLAT_DBG_ASSERT(sizeof(Interface->PhysicalAddress) == sizeof(Route->LocalLinkLayerAddress));
|
||||
|
@ -207,7 +208,7 @@ CxPlatResolveRoute(
|
|||
Route->NextHopLinkLayerAddress,
|
||||
IpnetRow.PhysicalAddress,
|
||||
sizeof(Route->NextHopLinkLayerAddress)) == 0)) {
|
||||
CXPLAT_ROUTE_RESOLUTION_WORKER* Worker = Socket->Datapath->RouteResolutionWorker;
|
||||
CXPLAT_ROUTE_RESOLUTION_WORKER* Worker = Socket->RawDatapath->RouteResolutionWorker;
|
||||
CXPLAT_ROUTE_RESOLUTION_OPERATION* Operation = CxPlatPoolAlloc(&Worker->OperationPool);
|
||||
if (Operation == NULL) {
|
||||
QuicTraceEvent(
|
||||
|
@ -246,13 +247,14 @@ Done:
|
|||
QUIC_STATUS
|
||||
CxPlatTryAddSocket(
|
||||
_In_ CXPLAT_SOCKET_POOL* Pool,
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
)
|
||||
{
|
||||
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
|
||||
int Result;
|
||||
CXPLAT_HASHTABLE_LOOKUP_CONTEXT Context;
|
||||
CXPLAT_HASHTABLE_ENTRY* Entry;
|
||||
int Option;
|
||||
QUIC_ADDR MappedAddress = {0};
|
||||
SOCKET TempUdpSocket = INVALID_SOCKET;
|
||||
int AssignedLocalAddressLength;
|
||||
|
@ -262,50 +264,30 @@ CxPlatTryAddSocket(
|
|||
// binding an auxiliary (dual stack) socket.
|
||||
//
|
||||
|
||||
Socket->AuxSocket =
|
||||
socket(
|
||||
AF_INET6,
|
||||
Socket->UseTcp ? SOCK_STREAM : SOCK_DGRAM,
|
||||
Socket->UseTcp ? IPPROTO_TCP : IPPROTO_UDP);
|
||||
if (Socket->AuxSocket == INVALID_SOCKET) {
|
||||
int WsaError = SocketError();
|
||||
QuicTraceEvent(
|
||||
DatapathErrorStatus,
|
||||
"[data][%p] ERROR, %u, %s.",
|
||||
Socket,
|
||||
WsaError,
|
||||
"socket");
|
||||
Status = HRESULT_FROM_WIN32(WsaError);
|
||||
goto Error;
|
||||
}
|
||||
if (Socket->UseTcp) {
|
||||
Socket->AuxSocket =
|
||||
socket(
|
||||
AF_INET6,
|
||||
SOCK_STREAM,
|
||||
IPPROTO_TCP);
|
||||
if (Socket->AuxSocket == INVALID_SOCKET) {
|
||||
int WsaError = SocketError();
|
||||
QuicTraceEvent(
|
||||
DatapathErrorStatus,
|
||||
"[data][%p] ERROR, %u, %s.",
|
||||
Socket,
|
||||
WsaError,
|
||||
"socket");
|
||||
Status = HRESULT_FROM_WIN32(WsaError);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
int Option = FALSE;
|
||||
Result =
|
||||
setsockopt(
|
||||
Socket->AuxSocket,
|
||||
IPPROTO_IPV6,
|
||||
IPV6_V6ONLY,
|
||||
(char*)&Option,
|
||||
sizeof(Option));
|
||||
if (Result == SOCKET_ERROR) {
|
||||
int WsaError = SocketError();
|
||||
QuicTraceEvent(
|
||||
DatapathErrorStatus,
|
||||
"[data][%p] ERROR, %u, %s.",
|
||||
Socket,
|
||||
WsaError,
|
||||
"Set IPV6_V6ONLY");
|
||||
Status = HRESULT_FROM_WIN32(WsaError);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (Socket->CibirIdLength) {
|
||||
Option = TRUE;
|
||||
Option = FALSE;
|
||||
Result =
|
||||
setsockopt(
|
||||
Socket->AuxSocket,
|
||||
SOL_SOCKET,
|
||||
SO_REUSEADDR,
|
||||
IPPROTO_IPV6,
|
||||
IPV6_V6ONLY,
|
||||
(char*)&Option,
|
||||
sizeof(Option));
|
||||
if (Result == SOCKET_ERROR) {
|
||||
|
@ -315,49 +297,78 @@ CxPlatTryAddSocket(
|
|||
"[data][%p] ERROR, %u, %s.",
|
||||
Socket,
|
||||
WsaError,
|
||||
"Set SO_REUSEADDR");
|
||||
"Set IPV6_V6ONLY");
|
||||
Status = HRESULT_FROM_WIN32(WsaError);
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
|
||||
CxPlatConvertToMappedV6(&Socket->LocalAddress, &MappedAddress);
|
||||
#if QUIC_ADDRESS_FAMILY_INET6 != AF_INET6
|
||||
if (MappedAddress.Ipv6.sin6_family == QUIC_ADDRESS_FAMILY_INET6) {
|
||||
MappedAddress.Ipv6.sin6_family = AF_INET6;
|
||||
}
|
||||
#endif
|
||||
|
||||
CxPlatRwLockAcquireExclusive(&Pool->Lock);
|
||||
|
||||
Result =
|
||||
bind(
|
||||
Socket->AuxSocket,
|
||||
(struct sockaddr*)&MappedAddress,
|
||||
sizeof(MappedAddress));
|
||||
if (Result == SOCKET_ERROR) {
|
||||
int WsaError = SocketError();
|
||||
QuicTraceEvent(
|
||||
DatapathErrorStatus,
|
||||
"[data][%p] ERROR, %u, %s.",
|
||||
Socket,
|
||||
WsaError,
|
||||
"bind");
|
||||
CxPlatRwLockReleaseExclusive(&Pool->Lock);
|
||||
Status = HRESULT_FROM_WIN32(WsaError);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (Socket->Connected) {
|
||||
CxPlatZeroMemory(&MappedAddress, sizeof(MappedAddress));
|
||||
CxPlatConvertToMappedV6(&Socket->RemoteAddress, &MappedAddress);
|
||||
if (Socket->CibirIdLength) {
|
||||
Option = TRUE;
|
||||
Result =
|
||||
setsockopt(
|
||||
Socket->AuxSocket,
|
||||
SOL_SOCKET,
|
||||
SO_REUSEADDR,
|
||||
(char*)&Option,
|
||||
sizeof(Option));
|
||||
if (Result == SOCKET_ERROR) {
|
||||
int WsaError = SocketError();
|
||||
QuicTraceEvent(
|
||||
DatapathErrorStatus,
|
||||
"[data][%p] ERROR, %u, %s.",
|
||||
Socket,
|
||||
WsaError,
|
||||
"Set SO_REUSEADDR");
|
||||
Status = HRESULT_FROM_WIN32(WsaError);
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
|
||||
CxPlatConvertToMappedV6(&Socket->LocalAddress, &MappedAddress);
|
||||
#if QUIC_ADDRESS_FAMILY_INET6 != AF_INET6
|
||||
if (MappedAddress.Ipv6.sin6_family == QUIC_ADDRESS_FAMILY_INET6) {
|
||||
MappedAddress.Ipv6.sin6_family = AF_INET6;
|
||||
}
|
||||
#endif
|
||||
if (Socket->UseTcp) {
|
||||
}
|
||||
|
||||
CxPlatRwLockAcquireExclusive(&Pool->Lock);
|
||||
|
||||
if (Socket->UseTcp) {
|
||||
QUIC_ADDR_STR LocalAddressString = {0};
|
||||
QuicAddrToString(&MappedAddress, &LocalAddressString);
|
||||
QuicTraceLogVerbose(
|
||||
DatapathTcpAuxBinding,
|
||||
"[data][%p] Binding TCP socket to %s",
|
||||
Socket,
|
||||
LocalAddressString.Address);
|
||||
Result =
|
||||
bind(
|
||||
Socket->AuxSocket,
|
||||
(struct sockaddr*)&MappedAddress,
|
||||
sizeof(MappedAddress));
|
||||
if (Result == SOCKET_ERROR) {
|
||||
int WsaError = SocketError();
|
||||
QuicTraceEvent(
|
||||
DatapathErrorStatus,
|
||||
"[data][%p] ERROR, %u, %s.",
|
||||
Socket,
|
||||
WsaError,
|
||||
"bind");
|
||||
CxPlatRwLockReleaseExclusive(&Pool->Lock);
|
||||
Status = HRESULT_FROM_WIN32(WsaError);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (Socket->Connected) {
|
||||
CxPlatZeroMemory(&MappedAddress, sizeof(MappedAddress));
|
||||
CxPlatConvertToMappedV6(&Socket->RemoteAddress, &MappedAddress);
|
||||
|
||||
#if QUIC_ADDRESS_FAMILY_INET6 != AF_INET6
|
||||
if (MappedAddress.Ipv6.sin6_family == QUIC_ADDRESS_FAMILY_INET6) {
|
||||
MappedAddress.Ipv6.sin6_family = AF_INET6;
|
||||
}
|
||||
#endif
|
||||
//
|
||||
// Create a temporary UDP socket bound to a wildcard port
|
||||
// and connect this socket to the remote address.
|
||||
|
@ -480,23 +491,6 @@ CxPlatTryAddSocket(
|
|||
Socket->LocalAddress.Ipv4.sin_port = LocalPortChosen;
|
||||
CXPLAT_FRE_ASSERT(Socket->LocalAddress.Ipv4.sin_port != 0);
|
||||
} else {
|
||||
Result =
|
||||
connect(
|
||||
Socket->AuxSocket,
|
||||
(struct sockaddr*)&MappedAddress,
|
||||
sizeof(MappedAddress));
|
||||
if (Result == SOCKET_ERROR) {
|
||||
int WsaError = SocketError();
|
||||
QuicTraceEvent(
|
||||
DatapathErrorStatus,
|
||||
"[data][%p] ERROR, %u, %s.",
|
||||
Socket,
|
||||
WsaError,
|
||||
"connect failed");
|
||||
CxPlatRwLockReleaseExclusive(&Pool->Lock);
|
||||
Status = HRESULT_FROM_WIN32(WsaError);
|
||||
goto Error;
|
||||
}
|
||||
AssignedLocalAddressLength = sizeof(Socket->LocalAddress);
|
||||
Result =
|
||||
getsockname(
|
||||
|
@ -517,31 +511,11 @@ CxPlatTryAddSocket(
|
|||
}
|
||||
CxPlatConvertFromMappedV6(&Socket->LocalAddress, &Socket->LocalAddress);
|
||||
}
|
||||
} else {
|
||||
AssignedLocalAddressLength = sizeof(Socket->LocalAddress);
|
||||
Result =
|
||||
getsockname(
|
||||
Socket->AuxSocket,
|
||||
(struct sockaddr*)&Socket->LocalAddress,
|
||||
&AssignedLocalAddressLength);
|
||||
if (Result == SOCKET_ERROR) {
|
||||
int WsaError = SocketError();
|
||||
QuicTraceEvent(
|
||||
DatapathErrorStatus,
|
||||
"[data][%p] ERROR, %u, %s.",
|
||||
Socket,
|
||||
WsaError,
|
||||
"getsockname");
|
||||
CxPlatRwLockReleaseExclusive(&Pool->Lock);
|
||||
Status = HRESULT_FROM_WIN32(WsaError);
|
||||
goto Error;
|
||||
}
|
||||
CxPlatConvertFromMappedV6(&Socket->LocalAddress, &Socket->LocalAddress);
|
||||
}
|
||||
|
||||
Entry = CxPlatHashtableLookup(&Pool->Sockets, Socket->LocalAddress.Ipv4.sin_port, &Context);
|
||||
while (Entry != NULL) {
|
||||
CXPLAT_SOCKET* Temp = CXPLAT_CONTAINING_RECORD(Entry, CXPLAT_SOCKET, Entry);
|
||||
CXPLAT_SOCKET_RAW* Temp = CXPLAT_CONTAINING_RECORD(Entry, CXPLAT_SOCKET_RAW, Entry);
|
||||
if (CxPlatSocketCompare(Temp, &Socket->LocalAddress, &Socket->RemoteAddress)) {
|
||||
Status = QUIC_STATUS_ADDRESS_IN_USE;
|
||||
break;
|
||||
|
|
|
@ -45,7 +45,7 @@ CxPlatDataPathRouteWorkerUninitialize(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathRouteWorkerInitialize(
|
||||
_Inout_ CXPLAT_DATAPATH* DataPath
|
||||
_Inout_ CXPLAT_DATAPATH_RAW* DataPath
|
||||
)
|
||||
{
|
||||
QUIC_STATUS Status;
|
||||
|
@ -104,36 +104,23 @@ Error:
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathInitialize(
|
||||
RawDataPathInitialize(
|
||||
_In_ uint32_t ClientRecvContextLength,
|
||||
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
|
||||
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
|
||||
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
|
||||
_Out_ CXPLAT_DATAPATH** NewDataPath
|
||||
_In_opt_ const CXPLAT_DATAPATH* ParentDataPath,
|
||||
_Out_ CXPLAT_DATAPATH_RAW** NewDataPath
|
||||
)
|
||||
{
|
||||
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
|
||||
const size_t DatapathSize = CxPlatDpRawGetDatapathSize(Config);
|
||||
BOOLEAN DpRawInitialized = FALSE;
|
||||
BOOLEAN SockPoolInitialized = FALSE;
|
||||
CXPLAT_FRE_ASSERT(DatapathSize > sizeof(CXPLAT_DATAPATH));
|
||||
|
||||
UNREFERENCED_PARAMETER(TcpCallbacks);
|
||||
|
||||
if (NewDataPath == NULL) {
|
||||
return QUIC_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (UdpCallbacks != NULL) {
|
||||
if (UdpCallbacks->Receive == NULL || UdpCallbacks->Unreachable == NULL) {
|
||||
return QUIC_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CxPlatWorkersLazyStart(Config)) {
|
||||
return QUIC_STATUS_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
CXPLAT_DATAPATH* DataPath = CXPLAT_ALLOC_PAGED(DatapathSize, QUIC_POOL_DATAPATH);
|
||||
CXPLAT_DATAPATH_RAW* DataPath = CXPLAT_ALLOC_PAGED(DatapathSize, QUIC_POOL_DATAPATH);
|
||||
if (DataPath == NULL) {
|
||||
QuicTraceEvent(
|
||||
AllocFailure,
|
||||
|
@ -145,10 +132,6 @@ CxPlatDataPathInitialize(
|
|||
CxPlatZeroMemory(DataPath, DatapathSize);
|
||||
CXPLAT_FRE_ASSERT(CxPlatRundownAcquire(&CxPlatWorkerRundown));
|
||||
|
||||
if (UdpCallbacks) {
|
||||
DataPath->UdpHandlers = *UdpCallbacks;
|
||||
}
|
||||
|
||||
if (Config && (Config->Flags & QUIC_EXECUTION_CONFIG_FLAG_QTIP)) {
|
||||
DataPath->UseTcp = TRUE;
|
||||
}
|
||||
|
@ -171,6 +154,7 @@ CxPlatDataPathInitialize(
|
|||
}
|
||||
|
||||
*NewDataPath = DataPath;
|
||||
DataPath->ParentDataPath = ParentDataPath;
|
||||
DataPath = NULL;
|
||||
|
||||
Error:
|
||||
|
@ -195,8 +179,8 @@ Error:
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDataPathUninitialize(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
RawDataPathUninitialize(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
)
|
||||
{
|
||||
if (Datapath != NULL) {
|
||||
|
@ -213,7 +197,7 @@ CxPlatDataPathUninitialize(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDataPathUninitializeComplete(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
)
|
||||
{
|
||||
#if DEBUG
|
||||
|
@ -228,8 +212,8 @@ CxPlatDataPathUninitializeComplete(
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDataPathUpdateConfig(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
RawDataPathUpdateConfig(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_ QUIC_EXECUTION_CONFIG* Config
|
||||
)
|
||||
{
|
||||
|
@ -238,8 +222,8 @@ CxPlatDataPathUpdateConfig(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
uint32_t
|
||||
CxPlatDataPathGetSupportedFeatures(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
RawDataPathGetSupportedFeatures(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
)
|
||||
{
|
||||
return CXPLAT_DATAPATH_FEATURE_RAW;
|
||||
|
@ -247,7 +231,7 @@ CxPlatDataPathGetSupportedFeatures(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
CxPlatDataPathIsPaddingPreferred(
|
||||
RawDataPathIsPaddingPreferred(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
)
|
||||
{
|
||||
|
@ -255,215 +239,72 @@ CxPlatDataPathIsPaddingPreferred(
|
|||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
_Success_(QUIC_SUCCEEDED(return))
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathGetLocalAddresses(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_Outptr_ _At_(*Addresses, __drv_allocatesMem(Mem))
|
||||
CXPLAT_ADAPTER_ADDRESS** Addresses,
|
||||
_Out_ uint32_t* AddressesCount
|
||||
)
|
||||
{
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
_Success_(QUIC_SUCCEEDED(return))
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathGetGatewayAddresses(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_Outptr_ _At_(*GatewayAddresses, __drv_allocatesMem(Mem))
|
||||
QUIC_ADDR** GatewayAddresses,
|
||||
_Out_ uint32_t* GatewayAddressesCount
|
||||
)
|
||||
{
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatDataPathPopulateTargetAddress(
|
||||
_In_ ADDRESS_FAMILY Family,
|
||||
_In_ ADDRINFOW *Ai,
|
||||
_Out_ SOCKADDR_INET* Address
|
||||
)
|
||||
{
|
||||
if (Ai->ai_addr->sa_family == QUIC_ADDRESS_FAMILY_INET6) {
|
||||
//
|
||||
// Is this a mapped ipv4 one?
|
||||
//
|
||||
PSOCKADDR_IN6 SockAddr6 = (PSOCKADDR_IN6)Ai->ai_addr;
|
||||
|
||||
if (Family == QUIC_ADDRESS_FAMILY_UNSPEC && IN6ADDR_ISV4MAPPED(SockAddr6))
|
||||
{
|
||||
PSOCKADDR_IN SockAddr4 = &Address->Ipv4;
|
||||
//
|
||||
// Get the ipv4 address from the mapped address.
|
||||
//
|
||||
SockAddr4->sin_family = QUIC_ADDRESS_FAMILY_INET;
|
||||
SockAddr4->sin_addr =
|
||||
*(IN_ADDR UNALIGNED *)
|
||||
IN6_GET_ADDR_V4MAPPED(&SockAddr6->sin6_addr);
|
||||
SockAddr4->sin_port = SockAddr6->sin6_port;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CxPlatCopyMemory(Address, Ai->ai_addr, Ai->ai_addrlen);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathResolveAddress(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_z_ const char* HostName,
|
||||
_Inout_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
QUIC_STATUS Status;
|
||||
PWSTR HostNameW = NULL;
|
||||
ADDRINFOW Hints = { 0 };
|
||||
ADDRINFOW *Ai;
|
||||
|
||||
Status =
|
||||
CxPlatUtf8ToWideChar(
|
||||
HostName,
|
||||
QUIC_POOL_PLATFORM_TMP_ALLOC,
|
||||
&HostNameW);
|
||||
if (QUIC_FAILED(Status)) {
|
||||
QuicTraceEvent(
|
||||
LibraryErrorStatus,
|
||||
"[ lib] ERROR, %u, %s.",
|
||||
Status,
|
||||
"Convert HostName to unicode");
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Prepopulate hint with input family. It might be unspecified.
|
||||
//
|
||||
Hints.ai_family = Address->si_family;
|
||||
|
||||
//
|
||||
// Try numeric name first.
|
||||
//
|
||||
Hints.ai_flags = AI_NUMERICHOST;
|
||||
if (GetAddrInfoW(HostNameW, NULL, &Hints, &Ai) == 0) {
|
||||
CxPlatDataPathPopulateTargetAddress((ADDRESS_FAMILY)Hints.ai_family, Ai, Address);
|
||||
FreeAddrInfoW(Ai);
|
||||
Status = QUIC_STATUS_SUCCESS;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Try canonical host name.
|
||||
//
|
||||
Hints.ai_flags = AI_CANONNAME;
|
||||
if (GetAddrInfoW(HostNameW, NULL, &Hints, &Ai) == 0) {
|
||||
CxPlatDataPathPopulateTargetAddress((ADDRESS_FAMILY)Hints.ai_family, Ai, Address);
|
||||
FreeAddrInfoW(Ai);
|
||||
Status = QUIC_STATUS_SUCCESS;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
QuicTraceEvent(
|
||||
LibraryError,
|
||||
"[ lib] ERROR, %s.",
|
||||
"Resolving hostname to IP");
|
||||
QuicTraceLogError(
|
||||
DatapathResolveHostNameFailed,
|
||||
"[%p] Couldn't resolve hostname '%s' to an IP address",
|
||||
Datapath,
|
||||
HostName);
|
||||
Status = HRESULT_FROM_WIN32(WSAHOST_NOT_FOUND);
|
||||
|
||||
Exit:
|
||||
|
||||
if (HostNameW != NULL) {
|
||||
CXPLAT_FREE(HostNameW, QUIC_POOL_PLATFORM_TMP_ALLOC);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateUdp(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
RawSocketCreateUdp(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Raw,
|
||||
_In_ const CXPLAT_UDP_CONFIG* Config,
|
||||
_Out_ CXPLAT_SOCKET** NewSocket
|
||||
_Inout_ CXPLAT_SOCKET_RAW* Socket
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Socket != NULL);
|
||||
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
|
||||
|
||||
*NewSocket = CXPLAT_ALLOC_PAGED(sizeof(CXPLAT_SOCKET), QUIC_POOL_SOCKET);
|
||||
if (*NewSocket == NULL) {
|
||||
QuicTraceEvent(
|
||||
AllocFailure,
|
||||
"Allocation of '%s' failed. (%llu bytes)",
|
||||
"CXPLAT_SOCKET",
|
||||
sizeof(CXPLAT_SOCKET));
|
||||
Status = QUIC_STATUS_OUT_OF_MEMORY;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
QuicTraceEvent(
|
||||
DatapathCreated,
|
||||
"[data][%p] Created, local=%!ADDR!, remote=%!ADDR!",
|
||||
*NewSocket,
|
||||
CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress),
|
||||
CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress));
|
||||
|
||||
CxPlatZeroMemory(*NewSocket, sizeof(CXPLAT_SOCKET));
|
||||
CxPlatRundownInitialize(&(*NewSocket)->Rundown);
|
||||
(*NewSocket)->Datapath = Datapath;
|
||||
(*NewSocket)->CallbackContext = Config->CallbackContext;
|
||||
(*NewSocket)->CibirIdLength = Config->CibirIdLength;
|
||||
(*NewSocket)->CibirIdOffsetSrc = Config->CibirIdOffsetSrc;
|
||||
(*NewSocket)->CibirIdOffsetDst = Config->CibirIdOffsetDst;
|
||||
(*NewSocket)->UseTcp = Datapath->UseTcp;
|
||||
CxPlatRundownInitialize(&Socket->Rundown);
|
||||
Socket->RawDatapath = Raw;
|
||||
Socket->CibirIdLength = Config->CibirIdLength;
|
||||
Socket->CibirIdOffsetSrc = Config->CibirIdOffsetSrc;
|
||||
Socket->CibirIdOffsetDst = Config->CibirIdOffsetDst;
|
||||
if (Config->CibirIdLength) {
|
||||
memcpy((*NewSocket)->CibirId, Config->CibirId, Config->CibirIdLength);
|
||||
memcpy(Socket->CibirId, Config->CibirId, Config->CibirIdLength);
|
||||
}
|
||||
|
||||
if (Config->RemoteAddress) {
|
||||
CXPLAT_FRE_ASSERT(!QuicAddrIsWildCard(Config->RemoteAddress)); // No wildcard remote addresses allowed.
|
||||
(*NewSocket)->Connected = TRUE;
|
||||
(*NewSocket)->RemoteAddress = *Config->RemoteAddress;
|
||||
if (Socket->UseTcp) {
|
||||
Socket->RemoteAddress = *Config->RemoteAddress;
|
||||
}
|
||||
Socket->Connected = TRUE;
|
||||
}
|
||||
|
||||
if (Config->LocalAddress) {
|
||||
(*NewSocket)->LocalAddress = *Config->LocalAddress;
|
||||
if (Socket->UseTcp) {
|
||||
Socket->LocalAddress = *Config->LocalAddress;
|
||||
}
|
||||
if (QuicAddrIsWildCard(Config->LocalAddress)) {
|
||||
if (!(*NewSocket)->Connected) {
|
||||
(*NewSocket)->Wildcard = TRUE;
|
||||
if (!Socket->Connected) {
|
||||
Socket->Wildcard = TRUE;
|
||||
}
|
||||
} else {
|
||||
CXPLAT_FRE_ASSERT((*NewSocket)->Connected); // Assumes only connected sockets fully specify local address
|
||||
} else if (!Socket->Connected) {
|
||||
// Assumes only connected sockets fully specify local address
|
||||
Status = QUIC_STATUS_INVALID_STATE;
|
||||
goto Error;
|
||||
}
|
||||
} else {
|
||||
QuicAddrSetFamily(&(*NewSocket)->LocalAddress, QUIC_ADDRESS_FAMILY_INET6);
|
||||
if (!(*NewSocket)->Connected) {
|
||||
(*NewSocket)->Wildcard = TRUE;
|
||||
if (Socket->UseTcp) {
|
||||
QuicAddrSetFamily(&Socket->LocalAddress, QUIC_ADDRESS_FAMILY_INET6);
|
||||
}
|
||||
if (!Socket->Connected) {
|
||||
Socket->Wildcard = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
CXPLAT_FRE_ASSERT((*NewSocket)->Wildcard ^ (*NewSocket)->Connected); // Assumes either a pure wildcard listener or a
|
||||
CXPLAT_FRE_ASSERT(Socket->Wildcard ^ Socket->Connected); // Assumes either a pure wildcard listener or a
|
||||
// connected socket; not both.
|
||||
|
||||
Status = CxPlatTryAddSocket(&Datapath->SocketPool, *NewSocket);
|
||||
Status = CxPlatTryAddSocket(&Raw->SocketPool, Socket);
|
||||
if (QUIC_FAILED(Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
CxPlatDpRawPlumbRulesOnSocket(*NewSocket, TRUE);
|
||||
CxPlatDpRawPlumbRulesOnSocket(Socket, TRUE);
|
||||
|
||||
Error:
|
||||
|
||||
if (QUIC_FAILED(Status)) {
|
||||
if (*NewSocket != NULL) {
|
||||
CxPlatRundownUninitialize(&(*NewSocket)->Rundown);
|
||||
CXPLAT_FREE(*NewSocket, QUIC_POOL_SOCKET);
|
||||
*NewSocket = NULL;
|
||||
if (Socket != NULL) {
|
||||
CxPlatRundownUninitialize(&Socket->Rundown);
|
||||
CxPlatZeroMemory(Socket, sizeof(CXPLAT_SOCKET_RAW) - sizeof(CXPLAT_SOCKET));
|
||||
Socket = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,12 +313,12 @@ Error:
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateTcp(
|
||||
RawCxPlatSocketCreateTcp(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_opt_ const QUIC_ADDR* LocalAddress,
|
||||
_In_ const QUIC_ADDR* RemoteAddress,
|
||||
_In_opt_ void* CallbackContext,
|
||||
_Out_ CXPLAT_SOCKET** Socket
|
||||
_Out_ CXPLAT_SOCKET_RAW** Socket
|
||||
)
|
||||
{
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
|
@ -485,11 +326,11 @@ CxPlatSocketCreateTcp(
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateTcpListener(
|
||||
RawSocketCreateTcpListener(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_opt_ const QUIC_ADDR* LocalAddress,
|
||||
_In_opt_ void* RecvCallbackContext,
|
||||
_Out_ CXPLAT_SOCKET** NewSocket
|
||||
_Out_ CXPLAT_SOCKET_RAW** NewSocket
|
||||
)
|
||||
{
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
|
@ -497,12 +338,12 @@ CxPlatSocketCreateTcpListener(
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatSocketDelete(
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
RawSocketDelete(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
)
|
||||
{
|
||||
CxPlatDpRawPlumbRulesOnSocket(Socket, FALSE);
|
||||
CxPlatRemoveSocket(&Socket->Datapath->SocketPool, Socket);
|
||||
CxPlatRemoveSocket(&Socket->RawDatapath->SocketPool, Socket);
|
||||
CxPlatRundownReleaseAndWait(&Socket->Rundown);
|
||||
if (Socket->PausedTcpSend) {
|
||||
CxPlatDpRawTxFree(Socket->PausedTcpSend);
|
||||
|
@ -512,13 +353,12 @@ CxPlatSocketDelete(
|
|||
CxPlatDpRawTxEnqueue(Socket->CachedRstSend);
|
||||
}
|
||||
|
||||
CXPLAT_FREE(Socket, QUIC_POOL_SOCKET);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
UINT16
|
||||
CxPlatSocketGetLocalMtu(
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
RawSocketGetLocalMtu(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
)
|
||||
{
|
||||
if (Socket->UseTcp) {
|
||||
|
@ -528,37 +368,17 @@ CxPlatSocketGetLocalMtu(
|
|||
}
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSocketGetLocalAddress(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
*Address = Socket->LocalAddress;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSocketGetRemoteAddress(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
*Address = Socket->RemoteAddress;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatDpRawRxEthernet(
|
||||
_In_ const CXPLAT_DATAPATH* Datapath,
|
||||
_In_ const CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_reads_(PacketCount)
|
||||
CXPLAT_RECV_DATA** Packets,
|
||||
_In_ uint16_t PacketCount
|
||||
)
|
||||
{
|
||||
for (uint16_t i = 0; i < PacketCount; i++) {
|
||||
CXPLAT_SOCKET* Socket = NULL;
|
||||
CXPLAT_SOCKET_RAW* Socket = NULL;
|
||||
CXPLAT_RECV_DATA* PacketChain = Packets[i];
|
||||
CXPLAT_DBG_ASSERT(PacketChain->Next == NULL);
|
||||
|
||||
|
@ -596,7 +416,7 @@ CxPlatDpRawRxEthernet(
|
|||
CXPLAT_DBG_ASSERT(Packets[i+1]->Next == NULL);
|
||||
i++;
|
||||
}
|
||||
Datapath->UdpHandlers.Receive(Socket, Socket->CallbackContext, (CXPLAT_RECV_DATA*)PacketChain);
|
||||
Datapath->ParentDataPath->UdpHandlers.Receive(CxPlatRawToSocket(Socket), Socket->ClientContext, (CXPLAT_RECV_DATA*)PacketChain);
|
||||
} else if (PacketChain->Reserved == L4_TYPE_TCP_SYN || PacketChain->Reserved == L4_TYPE_TCP_SYNACK) {
|
||||
CxPlatDpRawSocketAckSyn(Socket, PacketChain);
|
||||
CxPlatDpRawRxFree(PacketChain);
|
||||
|
@ -616,8 +436,8 @@ CxPlatDpRawRxEthernet(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatRecvDataReturn(
|
||||
_In_opt_ CXPLAT_RECV_DATA* RecvDataChain
|
||||
RawRecvDataReturn(
|
||||
_In_ CXPLAT_RECV_DATA* RecvDataChain
|
||||
)
|
||||
{
|
||||
CxPlatDpRawRxFree((const CXPLAT_RECV_DATA*)RecvDataChain);
|
||||
|
@ -626,8 +446,8 @@ CxPlatRecvDataReturn(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
CXPLAT_SEND_DATA*
|
||||
CxPlatSendDataAlloc(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
RawSendDataAlloc(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_Inout_ CXPLAT_SEND_CONFIG* Config
|
||||
)
|
||||
{
|
||||
|
@ -637,7 +457,7 @@ CxPlatSendDataAlloc(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
QUIC_BUFFER*
|
||||
CxPlatSendDataAllocBuffer(
|
||||
RawSendDataAllocBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ uint16_t MaxBufferLength
|
||||
)
|
||||
|
@ -648,7 +468,7 @@ CxPlatSendDataAllocBuffer(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSendDataFree(
|
||||
RawSendDataFree(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
|
@ -657,7 +477,7 @@ CxPlatSendDataFree(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSendDataFreeBuffer(
|
||||
RawSendDataFreeBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ QUIC_BUFFER* Buffer
|
||||
)
|
||||
|
@ -667,7 +487,7 @@ CxPlatSendDataFreeBuffer(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
CxPlatSendDataIsFull(
|
||||
RawSendDataIsFull(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
|
@ -678,8 +498,8 @@ CxPlatSendDataIsFull(
|
|||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketSend(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
RawSocketSend(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ const CXPLAT_ROUTE* Route,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
|
|
|
@ -25,22 +25,13 @@ typedef struct XDP_PARTITION XDP_PARTITION;
|
|||
typedef struct XDP_DATAPATH XDP_DATAPATH;
|
||||
typedef struct XDP_QUEUE XDP_QUEUE;
|
||||
|
||||
//
|
||||
// Type of IO.
|
||||
//
|
||||
typedef enum DATAPATH_IO_TYPE {
|
||||
DATAPATH_IO_SIGNATURE = 'XDPD',
|
||||
DATAPATH_IO_RECV = DATAPATH_IO_SIGNATURE + 1,
|
||||
DATAPATH_IO_SEND = DATAPATH_IO_SIGNATURE + 2
|
||||
} DATAPATH_IO_TYPE;
|
||||
|
||||
//
|
||||
// IO header for SQE->CQE based completions.
|
||||
//
|
||||
typedef struct DATAPATH_IO_SQE {
|
||||
DATAPATH_IO_TYPE IoType;
|
||||
typedef struct DATAPATH_XDP_IO_SQE {
|
||||
DATAPATH_XDP_IO_TYPE IoType;
|
||||
DATAPATH_SQE DatapathSqe;
|
||||
} DATAPATH_IO_SQE;
|
||||
} DATAPATH_XDP_IO_SQE;
|
||||
|
||||
typedef struct QUIC_CACHEALIGN XDP_PARTITION {
|
||||
CXPLAT_EXECUTION_CONTEXT Ec;
|
||||
|
|
|
@ -18,8 +18,9 @@ Abstract:
|
|||
#include "datapath_raw_xdp_linux.c.clog.h"
|
||||
#endif
|
||||
|
||||
typedef struct XDP_DATAPATH {
|
||||
CXPLAT_DATAPATH;
|
||||
// TODO: remove this exception when finalizing members
|
||||
typedef struct XDP_DATAPATH { // NOLINT(clang-analyzer-optin.performance.Padding)
|
||||
CXPLAT_DATAPATH_RAW;
|
||||
__attribute__((aligned(64)))
|
||||
//
|
||||
// Currently, all XDP interfaces share the same config.
|
||||
|
@ -177,7 +178,7 @@ CxPlatDpRawGetDatapathSize(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatDpRawInitialize(
|
||||
_Inout_ CXPLAT_DATAPATH* Datapath,
|
||||
_Inout_ CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_ uint32_t ClientRecvContextLength,
|
||||
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
|
||||
)
|
||||
|
@ -200,7 +201,7 @@ CxPlatDpRawRelease(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDpRawUninitialize(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
|
@ -209,7 +210,7 @@ CxPlatDpRawUninitialize(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDpRawPlumbRulesOnSocket(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ BOOLEAN IsCreated
|
||||
)
|
||||
{
|
||||
|
@ -249,7 +250,7 @@ CxPlatDpRawRxFree(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
CXPLAT_SEND_DATA*
|
||||
CxPlatDpRawTxAlloc(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_Inout_ CXPLAT_SEND_CONFIG* Config
|
||||
)
|
||||
{
|
||||
|
@ -289,7 +290,7 @@ CxPlatXdpExecute(
|
|||
}
|
||||
|
||||
void
|
||||
CxPlatDataPathProcessCqe(
|
||||
RawDataPathProcessCqe(
|
||||
_In_ CXPLAT_CQE* Cqe
|
||||
)
|
||||
{
|
||||
|
|
|
@ -24,8 +24,9 @@ Abstract:
|
|||
#endif
|
||||
|
||||
typedef struct XDP_DATAPATH {
|
||||
CXPLAT_DATAPATH;
|
||||
CXPLAT_DATAPATH_RAW;
|
||||
DECLSPEC_CACHEALIGN
|
||||
|
||||
//
|
||||
// Currently, all XDP interfaces share the same config.
|
||||
//
|
||||
|
@ -63,13 +64,13 @@ typedef struct XDP_QUEUE {
|
|||
struct XDP_QUEUE* Next;
|
||||
uint8_t* RxBuffers;
|
||||
HANDLE RxXsk;
|
||||
DATAPATH_IO_SQE RxIoSqe;
|
||||
DATAPATH_XDP_IO_SQE RxIoSqe;
|
||||
XSK_RING RxFillRing;
|
||||
XSK_RING RxRing;
|
||||
HANDLE RxProgram;
|
||||
uint8_t* TxBuffers;
|
||||
HANDLE TxXsk;
|
||||
DATAPATH_IO_SQE TxIoSqe;
|
||||
DATAPATH_XDP_IO_SQE TxIoSqe;
|
||||
XSK_RING TxRing;
|
||||
XSK_RING TxCompletionRing;
|
||||
BOOLEAN RxQueued;
|
||||
|
@ -546,9 +547,9 @@ CxPlatDpRawInterfaceInitialize(
|
|||
CxPlatListInitializeHead(&Queue->TxQueue);
|
||||
CxPlatListInitializeHead(&Queue->PartitionTxQueue);
|
||||
CxPlatDatapathSqeInitialize(&Queue->RxIoSqe.DatapathSqe, CXPLAT_CQE_TYPE_SOCKET_IO);
|
||||
Queue->RxIoSqe.IoType = DATAPATH_IO_RECV;
|
||||
Queue->RxIoSqe.IoType = DATAPATH_XDP_IO_RECV;
|
||||
CxPlatDatapathSqeInitialize(&Queue->TxIoSqe.DatapathSqe, CXPLAT_CQE_TYPE_SOCKET_IO);
|
||||
Queue->TxIoSqe.IoType = DATAPATH_IO_SEND;
|
||||
Queue->TxIoSqe.IoType = DATAPATH_XDP_IO_SEND;
|
||||
|
||||
//
|
||||
// RX datapath.
|
||||
|
@ -996,7 +997,7 @@ CxPlatDpRawGetDatapathSize(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatDpRawInitialize(
|
||||
_Inout_ CXPLAT_DATAPATH* Datapath,
|
||||
_Inout_ CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_ uint32_t ClientRecvContextLength,
|
||||
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
|
||||
)
|
||||
|
@ -1248,14 +1249,14 @@ CxPlatDpRawRelease(
|
|||
CxPlatFree(Interface, IF_TAG);
|
||||
}
|
||||
XdpUnloadApi(Xdp->XdpApiLoadContext, Xdp->XdpApi);
|
||||
CxPlatDataPathUninitializeComplete((CXPLAT_DATAPATH*)Xdp);
|
||||
CxPlatDataPathUninitializeComplete((CXPLAT_DATAPATH_RAW*)Xdp);
|
||||
}
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDpRawUninitialize(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
)
|
||||
{
|
||||
XDP_DATAPATH* Xdp = (XDP_DATAPATH*)Datapath;
|
||||
|
@ -1274,7 +1275,7 @@ CxPlatDpRawUninitialize(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDpRawUpdateConfig(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_ QUIC_EXECUTION_CONFIG* Config
|
||||
)
|
||||
{
|
||||
|
@ -1284,14 +1285,14 @@ CxPlatDpRawUpdateConfig(
|
|||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketUpdateQeo(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
RawSocketUpdateQeo(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_reads_(OffloadCount)
|
||||
const CXPLAT_QEO_CONNECTION* Offloads,
|
||||
_In_ uint32_t OffloadCount
|
||||
)
|
||||
{
|
||||
XDP_DATAPATH* Xdp = (XDP_DATAPATH*)Socket->Datapath;
|
||||
XDP_DATAPATH* Xdp = (XDP_DATAPATH*)Socket->RawDatapath;
|
||||
|
||||
XDP_QUIC_CONNECTION Connections[2];
|
||||
CXPLAT_FRE_ASSERT(OffloadCount == 2); // TODO - Refactor so upper layer struct matches XDP struct
|
||||
|
@ -1379,11 +1380,11 @@ CxPlatDpRawClearPortBit(
|
|||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDpRawPlumbRulesOnSocket(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ BOOLEAN IsCreated
|
||||
)
|
||||
{
|
||||
XDP_DATAPATH* Xdp = (XDP_DATAPATH*)Socket->Datapath;
|
||||
XDP_DATAPATH* Xdp = (XDP_DATAPATH*)Socket->RawDatapath;
|
||||
if (Socket->Wildcard) {
|
||||
XDP_RULE Rules[3] = {0};
|
||||
uint8_t RulesSize = 0;
|
||||
|
@ -1562,6 +1563,7 @@ CxPlatXdpRx(
|
|||
Packet->Queue = Queue;
|
||||
Packet->RouteStorage.Queue = Queue;
|
||||
Packet->RecvData.Route = &Packet->RouteStorage;
|
||||
Packet->RecvData.Route->DatapathType = Packet->RecvData.DatapathType = CXPLAT_DATAPATH_TYPE_RAW;
|
||||
Packet->RecvData.PartitionIndex = PartitionIndex;
|
||||
|
||||
CxPlatDpRawParseEthernet(
|
||||
|
@ -1610,7 +1612,7 @@ CxPlatXdpRx(
|
|||
}
|
||||
|
||||
if (PacketCount > 0) {
|
||||
CxPlatDpRawRxEthernet((CXPLAT_DATAPATH*)Xdp, Buffers, (uint16_t)PacketCount);
|
||||
CxPlatDpRawRxEthernet((CXPLAT_DATAPATH_RAW*)Xdp, Buffers, (uint16_t)PacketCount);
|
||||
}
|
||||
|
||||
if (XskRingError(&Queue->RxRing) && !Queue->Error) {
|
||||
|
@ -1671,7 +1673,7 @@ CxPlatDpRawRxFree(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
CXPLAT_SEND_DATA*
|
||||
CxPlatDpRawTxAlloc(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_Inout_ CXPLAT_SEND_CONFIG* Config
|
||||
)
|
||||
{
|
||||
|
@ -1686,6 +1688,7 @@ CxPlatDpRawTxAlloc(
|
|||
Packet->Buffer.Length = Config->MaxPacketSize;
|
||||
Packet->Buffer.Buffer = &Packet->FrameBuffer[HeaderBackfill.AllLayer];
|
||||
Packet->ECN = Config->ECN;
|
||||
Packet->DatapathType = Config->Route->DatapathType = CXPLAT_DATAPATH_TYPE_RAW;
|
||||
}
|
||||
|
||||
return (CXPLAT_SEND_DATA*)Packet;
|
||||
|
@ -1899,16 +1902,16 @@ CxPlatXdpExecute(
|
|||
}
|
||||
|
||||
void
|
||||
CxPlatDataPathProcessCqe(
|
||||
RawDataPathProcessCqe(
|
||||
_In_ CXPLAT_CQE* Cqe
|
||||
)
|
||||
{
|
||||
if (CxPlatCqeType(Cqe) == CXPLAT_CQE_TYPE_SOCKET_IO) {
|
||||
DATAPATH_IO_SQE* Sqe =
|
||||
CONTAINING_RECORD(CxPlatCqeUserData(Cqe), DATAPATH_IO_SQE, DatapathSqe);
|
||||
DATAPATH_XDP_IO_SQE* Sqe =
|
||||
CONTAINING_RECORD(CxPlatCqeUserData(Cqe), DATAPATH_XDP_IO_SQE, DatapathSqe);
|
||||
XDP_QUEUE* Queue;
|
||||
|
||||
if (Sqe->IoType == DATAPATH_IO_RECV) {
|
||||
if (Sqe->IoType == DATAPATH_XDP_IO_RECV) {
|
||||
Queue = CONTAINING_RECORD(Sqe, XDP_QUEUE, RxIoSqe);
|
||||
QuicTraceLogVerbose(
|
||||
XdpQueueAsyncIoRxComplete,
|
||||
|
@ -1916,7 +1919,7 @@ CxPlatDataPathProcessCqe(
|
|||
Queue);
|
||||
Queue->RxQueued = FALSE;
|
||||
} else {
|
||||
CXPLAT_DBG_ASSERT(Sqe->IoType == DATAPATH_IO_SEND);
|
||||
CXPLAT_DBG_ASSERT(Sqe->IoType == DATAPATH_XDP_IO_SEND);
|
||||
Queue = CONTAINING_RECORD(Sqe, XDP_QUEUE, TxIoSqe);
|
||||
QuicTraceLogVerbose(
|
||||
XdpQueueAsyncIoTxComplete,
|
||||
|
|
|
@ -0,0 +1,800 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
Licensed under the MIT License.
|
||||
|
||||
Abstract:
|
||||
|
||||
QUIC Datapath Implementation (User Mode)
|
||||
|
||||
--*/
|
||||
|
||||
#include "platform_internal.h"
|
||||
|
||||
#ifdef QUIC_CLOG
|
||||
#include "datapath_winuser.c.clog.h"
|
||||
#endif
|
||||
|
||||
#pragma warning(disable:4116) // unnamed type definition in parentheses
|
||||
|
||||
#pragma warning(disable:4100) // unreferenced
|
||||
#pragma warning(disable:6101) // uninitialized
|
||||
#pragma warning(disable:6386) // buffer overrun
|
||||
|
||||
#define IS_LOOPBACK(Address) ((Address.si_family == QUIC_ADDRESS_FAMILY_INET && \
|
||||
Address.Ipv4.sin_addr.S_un.S_addr == htonl(INADDR_LOOPBACK)) || \
|
||||
(Address.si_family == QUIC_ADDRESS_FAMILY_INET6 && \
|
||||
IN6_IS_ADDR_LOOPBACK(&Address.Ipv6.sin6_addr)))
|
||||
|
||||
#define DatapathType(SendData) ((CXPLAT_SEND_DATA_COMMON*)(SendData))->DatapathType
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathInitialize(
|
||||
_In_ uint32_t ClientRecvContextLength,
|
||||
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
|
||||
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
|
||||
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
|
||||
_Out_ CXPLAT_DATAPATH** NewDataPath
|
||||
)
|
||||
{
|
||||
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
|
||||
if (NewDataPath == NULL) {
|
||||
Status = QUIC_STATUS_INVALID_PARAMETER;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Status =
|
||||
DataPathInitialize(
|
||||
ClientRecvContextLength,
|
||||
UdpCallbacks,
|
||||
TcpCallbacks,
|
||||
Config,
|
||||
NewDataPath);
|
||||
if (QUIC_FAILED(Status)) {
|
||||
QuicTraceLogVerbose(
|
||||
DatapathInitFail,
|
||||
"[ dp] Failed to initialize datapath, status:%d", Status);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Status =
|
||||
RawDataPathInitialize(
|
||||
ClientRecvContextLength,
|
||||
Config,
|
||||
(*NewDataPath),
|
||||
&((*NewDataPath)->RawDataPath));
|
||||
if (QUIC_FAILED(Status)) {
|
||||
QuicTraceLogVerbose(
|
||||
RawDatapathInitFail,
|
||||
"[ raw] Failed to initialize raw datapath, status:%d", Status);
|
||||
Status = QUIC_STATUS_SUCCESS;
|
||||
(*NewDataPath)->RawDataPath = NULL;
|
||||
}
|
||||
|
||||
Error:
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDataPathUninitialize(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
)
|
||||
{
|
||||
if (Datapath->RawDataPath) {
|
||||
RawDataPathUninitialize(Datapath->RawDataPath);
|
||||
}
|
||||
DataPathUninitialize(Datapath);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatDataPathUpdateConfig(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ QUIC_EXECUTION_CONFIG* Config
|
||||
)
|
||||
{
|
||||
DataPathUpdateConfig(Datapath, Config);
|
||||
if (Datapath->RawDataPath) {
|
||||
RawDataPathUpdateConfig(Datapath->RawDataPath, Config);
|
||||
}
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
uint32_t
|
||||
CxPlatDataPathGetSupportedFeatures(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
)
|
||||
{
|
||||
if (Datapath->RawDataPath) {
|
||||
return DataPathGetSupportedFeatures(Datapath) |
|
||||
RawDataPathGetSupportedFeatures(Datapath->RawDataPath);
|
||||
}
|
||||
return DataPathGetSupportedFeatures(Datapath);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
CxPlatDataPathIsPaddingPreferred(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_USER ||
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_RAW);
|
||||
return
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_USER ?
|
||||
DataPathIsPaddingPreferred(Datapath) : RawDataPathIsPaddingPreferred(Datapath);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
_Success_(QUIC_SUCCEEDED(return))
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathGetLocalAddresses(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_Outptr_ _At_(*Addresses, __drv_allocatesMem(Mem))
|
||||
CXPLAT_ADAPTER_ADDRESS** Addresses,
|
||||
_Out_ uint32_t* AddressesCount
|
||||
)
|
||||
{
|
||||
const ULONG Flags =
|
||||
GAA_FLAG_INCLUDE_ALL_INTERFACES |
|
||||
GAA_FLAG_SKIP_ANYCAST |
|
||||
GAA_FLAG_SKIP_MULTICAST |
|
||||
GAA_FLAG_SKIP_DNS_SERVER |
|
||||
GAA_FLAG_SKIP_FRIENDLY_NAME |
|
||||
GAA_FLAG_SKIP_DNS_INFO;
|
||||
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
|
||||
ULONG AdapterAddressesSize = 0;
|
||||
PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL;
|
||||
uint32_t Index = 0;
|
||||
|
||||
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
|
||||
ULONG Error;
|
||||
do {
|
||||
Error =
|
||||
GetAdaptersAddresses(
|
||||
AF_UNSPEC,
|
||||
Flags,
|
||||
NULL,
|
||||
AdapterAddresses,
|
||||
&AdapterAddressesSize);
|
||||
if (Error == ERROR_BUFFER_OVERFLOW) {
|
||||
if (AdapterAddresses) {
|
||||
CXPLAT_FREE(AdapterAddresses, QUIC_POOL_DATAPATH_ADDRESSES);
|
||||
}
|
||||
AdapterAddresses = CXPLAT_ALLOC_NONPAGED(AdapterAddressesSize, QUIC_POOL_DATAPATH_ADDRESSES);
|
||||
if (!AdapterAddresses) {
|
||||
Error = ERROR_NOT_ENOUGH_MEMORY;
|
||||
QuicTraceEvent(
|
||||
AllocFailure,
|
||||
"Allocation of '%s' failed. (%llu bytes)",
|
||||
"PIP_ADAPTER_ADDRESSES",
|
||||
AdapterAddressesSize);
|
||||
}
|
||||
}
|
||||
} while (Error == ERROR_BUFFER_OVERFLOW);
|
||||
|
||||
if (Error != ERROR_SUCCESS) {
|
||||
QuicTraceEvent(
|
||||
LibraryErrorStatus,
|
||||
"[ lib] ERROR, %u, %s.",
|
||||
Error,
|
||||
"GetAdaptersAddresses");
|
||||
Status = HRESULT_FROM_WIN32(Error);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
for (PIP_ADAPTER_ADDRESSES Iter = AdapterAddresses; Iter != NULL; Iter = Iter->Next) {
|
||||
for (PIP_ADAPTER_UNICAST_ADDRESS_LH Iter2 = Iter->FirstUnicastAddress; Iter2 != NULL; Iter2 = Iter2->Next) {
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index == 0) {
|
||||
QuicTraceEvent(
|
||||
LibraryError,
|
||||
"[ lib] ERROR, %s.",
|
||||
"No local unicast addresses found");
|
||||
Status = QUIC_STATUS_NOT_FOUND;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
*Addresses = CXPLAT_ALLOC_NONPAGED(Index * sizeof(CXPLAT_ADAPTER_ADDRESS), QUIC_POOL_DATAPATH_ADDRESSES);
|
||||
if (*Addresses == NULL) {
|
||||
Status = QUIC_STATUS_OUT_OF_MEMORY;
|
||||
QuicTraceEvent(
|
||||
AllocFailure,
|
||||
"Allocation of '%s' failed. (%llu bytes)",
|
||||
"Addresses",
|
||||
Index * sizeof(CXPLAT_ADAPTER_ADDRESS));
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
CxPlatZeroMemory(*Addresses, Index * sizeof(CXPLAT_ADAPTER_ADDRESS));
|
||||
*AddressesCount = Index;
|
||||
Index = 0;
|
||||
|
||||
for (PIP_ADAPTER_ADDRESSES Iter = AdapterAddresses; Iter != NULL; Iter = Iter->Next) {
|
||||
for (PIP_ADAPTER_UNICAST_ADDRESS_LH Iter2 = Iter->FirstUnicastAddress; Iter2 != NULL; Iter2 = Iter2->Next) {
|
||||
CxPlatCopyMemory(
|
||||
&(*Addresses)[Index].Address,
|
||||
Iter2->Address.lpSockaddr,
|
||||
sizeof(QUIC_ADDR));
|
||||
(*Addresses)[Index].InterfaceIndex =
|
||||
Iter2->Address.lpSockaddr->sa_family == AF_INET ?
|
||||
(uint32_t)Iter->IfIndex : (uint32_t)Iter->Ipv6IfIndex;
|
||||
(*Addresses)[Index].InterfaceType = (uint16_t)Iter->IfType;
|
||||
(*Addresses)[Index].OperationStatus = (CXPLAT_OPERATION_STATUS)Iter->OperStatus;
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
|
||||
if (AdapterAddresses) {
|
||||
CXPLAT_FREE(AdapterAddresses, QUIC_POOL_DATAPATH_ADDRESSES);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
_Success_(QUIC_SUCCEEDED(return))
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathGetGatewayAddresses(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_Outptr_ _At_(*GatewayAddresses, __drv_allocatesMem(Mem))
|
||||
QUIC_ADDR** GatewayAddresses,
|
||||
_Out_ uint32_t* GatewayAddressesCount
|
||||
)
|
||||
{
|
||||
const ULONG Flags =
|
||||
GAA_FLAG_INCLUDE_GATEWAYS |
|
||||
GAA_FLAG_INCLUDE_ALL_INTERFACES |
|
||||
GAA_FLAG_SKIP_DNS_SERVER |
|
||||
GAA_FLAG_SKIP_MULTICAST;
|
||||
|
||||
UNREFERENCED_PARAMETER(Datapath);
|
||||
|
||||
ULONG AdapterAddressesSize = 0;
|
||||
PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL;
|
||||
uint32_t Index = 0;
|
||||
|
||||
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
|
||||
ULONG Error;
|
||||
do {
|
||||
Error =
|
||||
GetAdaptersAddresses(
|
||||
AF_UNSPEC,
|
||||
Flags,
|
||||
NULL,
|
||||
AdapterAddresses,
|
||||
&AdapterAddressesSize);
|
||||
if (Error == ERROR_BUFFER_OVERFLOW) {
|
||||
if (AdapterAddresses) {
|
||||
CXPLAT_FREE(AdapterAddresses, QUIC_POOL_DATAPATH_ADDRESSES);
|
||||
}
|
||||
AdapterAddresses = CXPLAT_ALLOC_NONPAGED(AdapterAddressesSize, QUIC_POOL_DATAPATH_ADDRESSES);
|
||||
if (!AdapterAddresses) {
|
||||
Error = ERROR_NOT_ENOUGH_MEMORY;
|
||||
QuicTraceEvent(
|
||||
AllocFailure,
|
||||
"Allocation of '%s' failed. (%llu bytes)",
|
||||
"PIP_ADAPTER_ADDRESSES",
|
||||
AdapterAddressesSize);
|
||||
}
|
||||
}
|
||||
} while (Error == ERROR_BUFFER_OVERFLOW);
|
||||
|
||||
if (Error != ERROR_SUCCESS) {
|
||||
QuicTraceEvent(
|
||||
LibraryErrorStatus,
|
||||
"[ lib] ERROR, %u, %s.",
|
||||
Error,
|
||||
"GetAdaptersAddresses");
|
||||
Status = HRESULT_FROM_WIN32(Error);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
for (PIP_ADAPTER_ADDRESSES Iter = AdapterAddresses; Iter != NULL; Iter = Iter->Next) {
|
||||
for (PIP_ADAPTER_GATEWAY_ADDRESS_LH Iter2 = Iter->FirstGatewayAddress; Iter2 != NULL; Iter2 = Iter2->Next) {
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index == 0) {
|
||||
QuicTraceEvent(
|
||||
LibraryError,
|
||||
"[ lib] ERROR, %s.",
|
||||
"No gateway server addresses found");
|
||||
Status = QUIC_STATUS_NOT_FOUND;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
*GatewayAddresses = CXPLAT_ALLOC_NONPAGED(Index * sizeof(QUIC_ADDR), QUIC_POOL_DATAPATH_ADDRESSES);
|
||||
if (*GatewayAddresses == NULL) {
|
||||
Status = QUIC_STATUS_OUT_OF_MEMORY;
|
||||
QuicTraceEvent(
|
||||
AllocFailure,
|
||||
"Allocation of '%s' failed. (%llu bytes)",
|
||||
"GatewayAddresses",
|
||||
Index * sizeof(QUIC_ADDR));
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
CxPlatZeroMemory(*GatewayAddresses, Index * sizeof(QUIC_ADDR));
|
||||
*GatewayAddressesCount = Index;
|
||||
Index = 0;
|
||||
|
||||
for (PIP_ADAPTER_ADDRESSES Iter = AdapterAddresses; Iter != NULL; Iter = Iter->Next) {
|
||||
for (PIP_ADAPTER_GATEWAY_ADDRESS_LH Iter2 = Iter->FirstGatewayAddress; Iter2 != NULL; Iter2 = Iter2->Next) {
|
||||
CxPlatCopyMemory(
|
||||
&(*GatewayAddresses)[Index],
|
||||
Iter2->Address.lpSockaddr,
|
||||
sizeof(QUIC_ADDR));
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
|
||||
if (AdapterAddresses) {
|
||||
CXPLAT_FREE(AdapterAddresses, QUIC_POOL_DATAPATH_ADDRESSES);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
// private func
|
||||
void
|
||||
CxPlatDataPathPopulateTargetAddress(
|
||||
_In_ ADDRESS_FAMILY Family,
|
||||
_In_ ADDRINFOW *Ai,
|
||||
_Out_ SOCKADDR_INET* Address
|
||||
)
|
||||
{
|
||||
if (Ai->ai_addr->sa_family == QUIC_ADDRESS_FAMILY_INET6) {
|
||||
//
|
||||
// Is this a mapped ipv4 one?
|
||||
//
|
||||
PSOCKADDR_IN6 SockAddr6 = (PSOCKADDR_IN6)Ai->ai_addr;
|
||||
|
||||
if (Family == QUIC_ADDRESS_FAMILY_UNSPEC && IN6ADDR_ISV4MAPPED(SockAddr6))
|
||||
{
|
||||
PSOCKADDR_IN SockAddr4 = &Address->Ipv4;
|
||||
//
|
||||
// Get the ipv4 address from the mapped address.
|
||||
//
|
||||
SockAddr4->sin_family = QUIC_ADDRESS_FAMILY_INET;
|
||||
SockAddr4->sin_addr =
|
||||
*(IN_ADDR UNALIGNED *)
|
||||
IN6_GET_ADDR_V4MAPPED(&SockAddr6->sin6_addr);
|
||||
SockAddr4->sin_port = SockAddr6->sin6_port;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CxPlatCopyMemory(Address, Ai->ai_addr, Ai->ai_addrlen);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatDataPathResolveAddress(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_z_ const char* HostName,
|
||||
_Inout_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
QUIC_STATUS Status;
|
||||
PWSTR HostNameW = NULL;
|
||||
ADDRINFOW Hints = { 0 };
|
||||
ADDRINFOW *Ai;
|
||||
|
||||
Status =
|
||||
CxPlatUtf8ToWideChar(
|
||||
HostName,
|
||||
QUIC_POOL_PLATFORM_TMP_ALLOC,
|
||||
&HostNameW);
|
||||
if (QUIC_FAILED(Status)) {
|
||||
QuicTraceEvent(
|
||||
LibraryErrorStatus,
|
||||
"[ lib] ERROR, %u, %s.",
|
||||
Status,
|
||||
"Convert HostName to unicode");
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Prepopulate hint with input family. It might be unspecified.
|
||||
//
|
||||
Hints.ai_family = Address->si_family;
|
||||
|
||||
//
|
||||
// Try numeric name first.
|
||||
//
|
||||
Hints.ai_flags = AI_NUMERICHOST;
|
||||
if (GetAddrInfoW(HostNameW, NULL, &Hints, &Ai) == 0) {
|
||||
CxPlatDataPathPopulateTargetAddress((ADDRESS_FAMILY)Hints.ai_family, Ai, Address);
|
||||
FreeAddrInfoW(Ai);
|
||||
Status = QUIC_STATUS_SUCCESS;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Try canonical host name.
|
||||
//
|
||||
Hints.ai_flags = AI_CANONNAME;
|
||||
if (GetAddrInfoW(HostNameW, NULL, &Hints, &Ai) == 0) {
|
||||
CxPlatDataPathPopulateTargetAddress((ADDRESS_FAMILY)Hints.ai_family, Ai, Address);
|
||||
FreeAddrInfoW(Ai);
|
||||
Status = QUIC_STATUS_SUCCESS;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
QuicTraceEvent(
|
||||
LibraryError,
|
||||
"[ lib] ERROR, %s.",
|
||||
"Resolving hostname to IP");
|
||||
QuicTraceLogError(
|
||||
DatapathResolveHostNameFailed,
|
||||
"[%p] Couldn't resolve hostname '%s' to an IP address",
|
||||
Datapath,
|
||||
HostName);
|
||||
Status = HRESULT_FROM_WIN32(WSAHOST_NOT_FOUND);
|
||||
|
||||
Exit:
|
||||
|
||||
if (HostNameW != NULL) {
|
||||
CXPLAT_FREE(HostNameW, QUIC_POOL_PLATFORM_TMP_ALLOC);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateUdp(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ const CXPLAT_UDP_CONFIG* Config,
|
||||
_Out_ CXPLAT_SOCKET** NewSocket
|
||||
)
|
||||
{
|
||||
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
|
||||
|
||||
Status =
|
||||
SocketCreateUdp(
|
||||
Datapath,
|
||||
Config,
|
||||
NewSocket);
|
||||
if (QUIC_FAILED(Status)) {
|
||||
QuicTraceLogVerbose(
|
||||
SockCreateFail,
|
||||
"[sock] Failed to create socket, status:%d", Status);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (Datapath->RawDataPath) {
|
||||
Status =
|
||||
RawSocketCreateUdp(
|
||||
Datapath->RawDataPath,
|
||||
Config,
|
||||
CxPlatSocketToRaw(*NewSocket));
|
||||
(*NewSocket)->RawSocketAvailable = QUIC_SUCCEEDED(Status);
|
||||
if (QUIC_FAILED(Status)) {
|
||||
QuicTraceLogVerbose(
|
||||
RawSockCreateFail,
|
||||
"[sock] Failed to create raw socket, status:%d", Status);
|
||||
if (Datapath->UseTcp) {
|
||||
CxPlatSocketDelete(*NewSocket);
|
||||
goto Error;
|
||||
}
|
||||
Status = QUIC_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Error:
|
||||
return Status;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateTcp(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_opt_ const QUIC_ADDR* LocalAddress,
|
||||
_In_ const QUIC_ADDR* RemoteAddress,
|
||||
_In_opt_ void* CallbackContext,
|
||||
_Out_ CXPLAT_SOCKET** NewSocket
|
||||
)
|
||||
{
|
||||
return SocketCreateTcp(
|
||||
Datapath,
|
||||
LocalAddress,
|
||||
RemoteAddress,
|
||||
CallbackContext,
|
||||
NewSocket);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketCreateTcpListener(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_opt_ const QUIC_ADDR* LocalAddress,
|
||||
_In_opt_ void* RecvCallbackContext,
|
||||
_Out_ CXPLAT_SOCKET** NewSocket
|
||||
)
|
||||
{
|
||||
return SocketCreateTcpListener(
|
||||
Datapath,
|
||||
LocalAddress,
|
||||
RecvCallbackContext,
|
||||
NewSocket);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatSocketDelete(
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
)
|
||||
{
|
||||
if (Socket->RawSocketAvailable) {
|
||||
RawSocketDelete(CxPlatSocketToRaw(Socket));
|
||||
}
|
||||
SocketDelete(Socket);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketUpdateQeo(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_reads_(OffloadCount)
|
||||
const CXPLAT_QEO_CONNECTION* Offloads,
|
||||
_In_ uint32_t OffloadCount
|
||||
)
|
||||
{
|
||||
if (Socket->UseTcp || (Socket->RawSocketAvailable &&
|
||||
!IS_LOOPBACK(Offloads[0].Address))) {
|
||||
return RawSocketUpdateQeo(CxPlatSocketToRaw(Socket), Offloads, OffloadCount);
|
||||
}
|
||||
return QUIC_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
UINT16
|
||||
CxPlatSocketGetLocalMtu(
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Socket != NULL);
|
||||
if (Socket->UseTcp || (Socket->RawSocketAvailable &&
|
||||
!IS_LOOPBACK(Socket->RemoteAddress))) {
|
||||
return RawSocketGetLocalMtu(CxPlatSocketToRaw(Socket));
|
||||
}
|
||||
return Socket->Mtu;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSocketGetLocalAddress(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Socket != NULL);
|
||||
*Address = Socket->LocalAddress;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSocketGetRemoteAddress(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Out_ QUIC_ADDR* Address
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Socket != NULL);
|
||||
*Address = Socket->RemoteAddress;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatRecvDataReturn(
|
||||
_In_opt_ CXPLAT_RECV_DATA* RecvDataChain
|
||||
)
|
||||
{
|
||||
if (RecvDataChain == NULL) {
|
||||
return;
|
||||
}
|
||||
CXPLAT_DBG_ASSERT(
|
||||
RecvDataChain->DatapathType == CXPLAT_DATAPATH_TYPE_USER ||
|
||||
RecvDataChain->DatapathType == CXPLAT_DATAPATH_TYPE_RAW);
|
||||
RecvDataChain->DatapathType == CXPLAT_DATAPATH_TYPE_USER ?
|
||||
RecvDataReturn(RecvDataChain) : RawRecvDataReturn(RecvDataChain);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
CXPLAT_SEND_DATA*
|
||||
CxPlatSendDataAlloc(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Inout_ CXPLAT_SEND_CONFIG* Config
|
||||
)
|
||||
{
|
||||
CXPLAT_SEND_DATA* SendData = NULL;
|
||||
// TODO: fallback?
|
||||
if (Socket->UseTcp || Config->Route->DatapathType == CXPLAT_DATAPATH_TYPE_RAW ||
|
||||
(Config->Route->DatapathType == CXPLAT_DATAPATH_TYPE_UNKNOWN &&
|
||||
Socket->RawSocketAvailable && !IS_LOOPBACK(Config->Route->RemoteAddress))) {
|
||||
SendData = RawSendDataAlloc(CxPlatSocketToRaw(Socket), Config);
|
||||
} else {
|
||||
SendData = SendDataAlloc(Socket, Config);
|
||||
}
|
||||
return SendData;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSendDataFree(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_USER ||
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_RAW);
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_USER ?
|
||||
SendDataFree(SendData) : RawSendDataFree(SendData);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
QUIC_BUFFER*
|
||||
CxPlatSendDataAllocBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ uint16_t MaxBufferLength
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_USER ||
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_RAW);
|
||||
return
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_USER ?
|
||||
SendDataAllocBuffer(SendData, MaxBufferLength) : RawSendDataAllocBuffer(SendData, MaxBufferLength);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
CxPlatSendDataFreeBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ QUIC_BUFFER* Buffer
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_USER ||
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_RAW);
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_USER ?
|
||||
SendDataFreeBuffer(SendData, Buffer) : RawSendDataFreeBuffer(SendData, Buffer);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
CxPlatSendDataIsFull(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_USER ||
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_RAW);
|
||||
return DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_USER ?
|
||||
SendDataIsFull(SendData) : RawSendDataIsFull(SendData);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatSocketSend(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ const CXPLAT_ROUTE* Route,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_USER ||
|
||||
DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_RAW);
|
||||
return DatapathType(SendData) == CXPLAT_DATAPATH_TYPE_USER ?
|
||||
SocketSend(Socket, Route, SendData) : RawSocketSend(CxPlatSocketToRaw(Socket), Route, SendData);
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatDataPathProcessCqe(
|
||||
_In_ CXPLAT_CQE* Cqe
|
||||
)
|
||||
{
|
||||
switch (CxPlatCqeType(Cqe)) {
|
||||
case CXPLAT_CQE_TYPE_SOCKET_IO: {
|
||||
DATAPATH_IO_SQE* Sqe =
|
||||
CONTAINING_RECORD(CxPlatCqeUserData(Cqe), DATAPATH_IO_SQE, DatapathSqe);
|
||||
if (Sqe->IoType == DATAPATH_XDP_IO_RECV || Sqe->IoType == DATAPATH_XDP_IO_SEND) {
|
||||
RawDataPathProcessCqe(Cqe);
|
||||
} else {
|
||||
DataPathProcessCqe(Cqe);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CXPLAT_CQE_TYPE_SOCKET_SHUTDOWN: {
|
||||
RawDataPathProcessCqe(Cqe);
|
||||
break;
|
||||
}
|
||||
default: CXPLAT_DBG_ASSERT(FALSE); break;
|
||||
}
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
QuicCopyRouteInfo(
|
||||
_Inout_ CXPLAT_ROUTE* DstRoute,
|
||||
_In_ CXPLAT_ROUTE* SrcRoute
|
||||
)
|
||||
{
|
||||
if (SrcRoute->DatapathType == CXPLAT_DATAPATH_TYPE_RAW) {
|
||||
CxPlatCopyMemory(DstRoute, SrcRoute, (uint8_t*)&SrcRoute->State - (uint8_t*)SrcRoute);
|
||||
CxPlatUpdateRoute(DstRoute, SrcRoute);
|
||||
} else if (SrcRoute->DatapathType == CXPLAT_DATAPATH_TYPE_USER) {
|
||||
*DstRoute = *SrcRoute;
|
||||
} else {
|
||||
CXPLAT_DBG_ASSERT(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CxPlatResolveRouteComplete(
|
||||
_In_ void* Connection,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_reads_bytes_(6) const uint8_t* PhysicalAddress,
|
||||
_In_ uint8_t PathId
|
||||
)
|
||||
{
|
||||
CXPLAT_DBG_ASSERT(Route->DatapathType != CXPLAT_DATAPATH_TYPE_USER);
|
||||
if (Route->State != RouteResolved) {
|
||||
RawResolveRouteComplete(Connection, Route, PhysicalAddress, PathId);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Tries to resolve route and neighbor for the given destination address.
|
||||
//
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
CxPlatResolveRoute(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_ uint8_t PathId,
|
||||
_In_ void* Context,
|
||||
_In_ CXPLAT_ROUTE_RESOLUTION_CALLBACK_HANDLER Callback
|
||||
)
|
||||
{
|
||||
if (Socket->UseTcp || Route->DatapathType == CXPLAT_DATAPATH_TYPE_RAW ||
|
||||
(Route->DatapathType == CXPLAT_DATAPATH_TYPE_UNKNOWN &&
|
||||
Socket->RawSocketAvailable && !IS_LOOPBACK(Route->RemoteAddress))) {
|
||||
return RawResolveRoute(CxPlatSocketToRaw(Socket), Route, PathId, Context, Callback);
|
||||
}
|
||||
Route->State = RouteResolved;
|
||||
return QUIC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
CxPlatUpdateRoute(
|
||||
_Inout_ CXPLAT_ROUTE* DstRoute,
|
||||
_In_ CXPLAT_ROUTE* SrcRoute
|
||||
)
|
||||
{
|
||||
if (SrcRoute->DatapathType == CXPLAT_DATAPATH_TYPE_RAW ||
|
||||
(SrcRoute->DatapathType == CXPLAT_DATAPATH_TYPE_UNKNOWN &&
|
||||
!IS_LOOPBACK(SrcRoute->RemoteAddress))) {
|
||||
RawUpdateRoute(DstRoute, SrcRoute);
|
||||
}
|
||||
}
|
||||
|
|
@ -1051,9 +1051,11 @@ CxPlatDataPathGetSupportedFeatures(
|
|||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
CxPlatDataPathIsPaddingPreferred(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(SendData);
|
||||
return !!(Datapath->Features & CXPLAT_DATAPATH_FEATURE_SEND_SEGMENTATION);
|
||||
}
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -39,6 +39,86 @@
|
|||
|
||||
#endif
|
||||
|
||||
typedef struct DATAPATH_SQE {
|
||||
uint32_t CqeType;
|
||||
#ifdef CXPLAT_SQE
|
||||
CXPLAT_SQE Sqe;
|
||||
#endif
|
||||
} DATAPATH_SQE;
|
||||
|
||||
typedef struct CXPLAT_DATAPATH_COMMON {
|
||||
//
|
||||
// The UDP callback function pointers.
|
||||
//
|
||||
CXPLAT_UDP_DATAPATH_CALLBACKS UdpHandlers;
|
||||
|
||||
//
|
||||
// The TCP callback function pointers.
|
||||
//
|
||||
CXPLAT_TCP_DATAPATH_CALLBACKS TcpHandlers;
|
||||
} CXPLAT_DATAPATH_COMMON;
|
||||
|
||||
typedef struct CXPLAT_SOCKET_COMMON {
|
||||
//
|
||||
// The local address and port.
|
||||
//
|
||||
QUIC_ADDR LocalAddress;
|
||||
|
||||
//
|
||||
// The remote address and port.
|
||||
//
|
||||
QUIC_ADDR RemoteAddress;
|
||||
} CXPLAT_SOCKET_COMMON;
|
||||
|
||||
typedef struct CXPLAT_SEND_DATA_COMMON {
|
||||
uint16_t DatapathType; // CXPLAT_DATAPATH_TYPE
|
||||
|
||||
//
|
||||
// The type of ECN markings needed for send.
|
||||
//
|
||||
uint8_t ECN; // CXPLAT_ECN_TYPE
|
||||
} CXPLAT_SEND_DATA_COMMON;
|
||||
|
||||
typedef enum CXPLAT_DATAPATH_TYPE {
|
||||
CXPLAT_DATAPATH_TYPE_UNKNOWN = 0,
|
||||
CXPLAT_DATAPATH_TYPE_USER,
|
||||
CXPLAT_DATAPATH_TYPE_RAW, // currently raw == xdp
|
||||
} CXPLAT_DATAPATH_TYPE;
|
||||
|
||||
//
|
||||
// Type of IO.
|
||||
//
|
||||
typedef enum DATAPATH_IO_TYPE {
|
||||
DATAPATH_IO_SIGNATURE = 'WINU',
|
||||
DATAPATH_IO_RECV = DATAPATH_IO_SIGNATURE + 1,
|
||||
DATAPATH_IO_SEND = DATAPATH_IO_SIGNATURE + 2,
|
||||
DATAPATH_IO_QUEUE_SEND = DATAPATH_IO_SIGNATURE + 3,
|
||||
DATAPATH_IO_ACCEPTEX = DATAPATH_IO_SIGNATURE + 4,
|
||||
DATAPATH_IO_CONNECTEX = DATAPATH_IO_SIGNATURE + 5,
|
||||
DATAPATH_IO_RIO_NOTIFY = DATAPATH_IO_SIGNATURE + 6,
|
||||
DATAPATH_IO_RIO_RECV = DATAPATH_IO_SIGNATURE + 7,
|
||||
DATAPATH_IO_RIO_SEND = DATAPATH_IO_SIGNATURE + 8,
|
||||
DATAPATH_IO_RECV_FAILURE = DATAPATH_IO_SIGNATURE + 9,
|
||||
DATAPATH_IO_MAX
|
||||
} DATAPATH_IO_TYPE;
|
||||
|
||||
//
|
||||
// Type of IO for XDP.
|
||||
//
|
||||
typedef enum DATAPATH_XDP_IO_TYPE {
|
||||
DATAPATH_XDP_IO_SIGNATURE = 'XDPD',
|
||||
DATAPATH_XDP_IO_RECV = DATAPATH_XDP_IO_SIGNATURE + 1,
|
||||
DATAPATH_XDP_IO_SEND = DATAPATH_XDP_IO_SIGNATURE + 2
|
||||
} DATAPATH_XDP_IO_TYPE;
|
||||
|
||||
//
|
||||
// IO header for SQE->CQE based completions.
|
||||
//
|
||||
typedef struct DATAPATH_IO_SQE {
|
||||
DATAPATH_IO_TYPE IoType;
|
||||
DATAPATH_SQE DatapathSqe;
|
||||
} DATAPATH_IO_SQE;
|
||||
|
||||
#ifdef _KERNEL_MODE
|
||||
|
||||
#define CXPLAT_BASE_REG_PATH L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\MsQuic\\Parameters\\"
|
||||
|
@ -104,6 +184,345 @@ typedef struct CX_PLATFORM {
|
|||
|
||||
} CX_PLATFORM;
|
||||
|
||||
typedef enum CXPLAT_SOCKET_TYPE {
|
||||
CXPLAT_SOCKET_UDP = 0,
|
||||
CXPLAT_SOCKET_TCP_LISTENER = 1,
|
||||
CXPLAT_SOCKET_TCP = 2,
|
||||
CXPLAT_SOCKET_TCP_SERVER = 3
|
||||
} CXPLAT_SOCKET_TYPE;
|
||||
|
||||
//
|
||||
// Represents a single IO completion port and thread for processing work that is
|
||||
// completed on a single processor.
|
||||
//
|
||||
typedef struct QUIC_CACHEALIGN CXPLAT_DATAPATH_PROC {
|
||||
|
||||
//
|
||||
// Parent datapath.
|
||||
//
|
||||
CXPLAT_DATAPATH* Datapath;
|
||||
|
||||
//
|
||||
// Event queue used for processing work.
|
||||
//
|
||||
CXPLAT_EVENTQ* EventQ;
|
||||
|
||||
//
|
||||
// Used to synchronize clean up.
|
||||
//
|
||||
CXPLAT_REF_COUNT RefCount;
|
||||
|
||||
//
|
||||
// The index into the execution config processor array.
|
||||
//
|
||||
uint16_t PartitionIndex;
|
||||
|
||||
//
|
||||
// Debug flags
|
||||
//
|
||||
uint8_t Uninitialized : 1;
|
||||
|
||||
//
|
||||
// Pool of send contexts to be shared by all sockets on this core.
|
||||
//
|
||||
CXPLAT_POOL SendDataPool;
|
||||
|
||||
//
|
||||
// Pool of send contexts to be shared by all RIO sockets on this core.
|
||||
//
|
||||
CXPLAT_POOL RioSendDataPool;
|
||||
|
||||
//
|
||||
// Pool of send buffers to be shared by all sockets on this core.
|
||||
//
|
||||
CXPLAT_POOL SendBufferPool;
|
||||
|
||||
//
|
||||
// Pool of large segmented send buffers to be shared by all sockets on this
|
||||
// core.
|
||||
//
|
||||
CXPLAT_POOL LargeSendBufferPool;
|
||||
|
||||
//
|
||||
// Pool of send buffers to be shared by all RIO sockets on this core.
|
||||
//
|
||||
CXPLAT_POOL RioSendBufferPool;
|
||||
|
||||
//
|
||||
// Pool of large segmented send buffers to be shared by all RIO sockets on
|
||||
// this core.
|
||||
//
|
||||
CXPLAT_POOL RioLargeSendBufferPool;
|
||||
|
||||
//
|
||||
// Pool of receive datagram contexts and buffers to be shared by all sockets
|
||||
// on this core.
|
||||
//
|
||||
CXPLAT_POOL RecvDatagramPool;
|
||||
|
||||
//
|
||||
// Pool of RIO receive datagram contexts and buffers to be shared by all
|
||||
// RIO sockets on this core.
|
||||
//
|
||||
CXPLAT_POOL RioRecvPool;
|
||||
|
||||
} CXPLAT_DATAPATH_PARTITION;
|
||||
|
||||
//
|
||||
// Per-processor socket state.
|
||||
//
|
||||
typedef struct QUIC_CACHEALIGN CXPLAT_SOCKET_PROC {
|
||||
//
|
||||
// Used to synchronize clean up.
|
||||
//
|
||||
CXPLAT_REF_COUNT RefCount;
|
||||
|
||||
//
|
||||
// Submission queue event for IO completion
|
||||
//
|
||||
DATAPATH_IO_SQE IoSqe;
|
||||
|
||||
//
|
||||
// Submission queue event for RIO IO completion
|
||||
//
|
||||
DATAPATH_IO_SQE RioSqe;
|
||||
|
||||
//
|
||||
// The datapath per-processor context.
|
||||
//
|
||||
CXPLAT_DATAPATH_PARTITION* DatapathProc;
|
||||
|
||||
//
|
||||
// Parent CXPLAT_SOCKET.
|
||||
//
|
||||
CXPLAT_SOCKET* Parent;
|
||||
|
||||
//
|
||||
// Socket handle to the networking stack.
|
||||
//
|
||||
SOCKET Socket;
|
||||
|
||||
//
|
||||
// Rundown for synchronizing upcalls to the app and downcalls on the Socket.
|
||||
//
|
||||
CXPLAT_RUNDOWN_REF RundownRef;
|
||||
|
||||
//
|
||||
// Flag indicates the socket started processing IO.
|
||||
//
|
||||
BOOLEAN IoStarted : 1;
|
||||
|
||||
//
|
||||
// Flag indicates a persistent out-of-memory failure for the receive path.
|
||||
//
|
||||
BOOLEAN RecvFailure : 1;
|
||||
|
||||
//
|
||||
// Debug Flags
|
||||
//
|
||||
uint8_t Uninitialized : 1;
|
||||
uint8_t Freed : 1;
|
||||
|
||||
//
|
||||
// The set of parameters/state passed to WsaRecvMsg for the IP stack to
|
||||
// populate to indicate the result of the receive.
|
||||
//
|
||||
|
||||
union {
|
||||
//
|
||||
// Normal TCP/UDP socket data
|
||||
//
|
||||
struct {
|
||||
RIO_CQ RioCq;
|
||||
RIO_RQ RioRq;
|
||||
ULONG RioRecvCount;
|
||||
ULONG RioSendCount;
|
||||
CXPLAT_LIST_ENTRY RioSendOverflow;
|
||||
BOOLEAN RioNotifyArmed;
|
||||
};
|
||||
//
|
||||
// TCP Listener socket data
|
||||
//
|
||||
struct {
|
||||
CXPLAT_SOCKET* AcceptSocket;
|
||||
char AcceptAddrSpace[
|
||||
sizeof(SOCKADDR_INET) + 16 +
|
||||
sizeof(SOCKADDR_INET) + 16
|
||||
];
|
||||
};
|
||||
};
|
||||
} CXPLAT_SOCKET_PROC;
|
||||
|
||||
//
|
||||
// Main structure for tracking all UDP abstractions.
|
||||
//
|
||||
typedef struct CXPLAT_DATAPATH {
|
||||
CXPLAT_DATAPATH_COMMON;
|
||||
|
||||
//
|
||||
// Function pointer to AcceptEx.
|
||||
//
|
||||
LPFN_ACCEPTEX AcceptEx;
|
||||
|
||||
//
|
||||
// Function pointer to ConnectEx.
|
||||
//
|
||||
LPFN_CONNECTEX ConnectEx;
|
||||
|
||||
//
|
||||
// Function pointer to WSASendMsg.
|
||||
//
|
||||
LPFN_WSASENDMSG WSASendMsg;
|
||||
|
||||
//
|
||||
// Function pointer to WSARecvMsg.
|
||||
//
|
||||
LPFN_WSARECVMSG WSARecvMsg;
|
||||
|
||||
//
|
||||
// Function pointer table for RIO.
|
||||
//
|
||||
RIO_EXTENSION_FUNCTION_TABLE RioDispatch;
|
||||
|
||||
//
|
||||
// Used to synchronize clean up.
|
||||
//
|
||||
CXPLAT_REF_COUNT RefCount;
|
||||
|
||||
//
|
||||
// Set of supported features.
|
||||
//
|
||||
uint32_t Features;
|
||||
|
||||
//
|
||||
// The size of each receive datagram array element, including client context,
|
||||
// internal context, and padding.
|
||||
//
|
||||
uint32_t DatagramStride;
|
||||
|
||||
//
|
||||
// The offset of the receive payload buffer from the start of the receive
|
||||
// context.
|
||||
//
|
||||
uint32_t RecvPayloadOffset;
|
||||
|
||||
//
|
||||
// The number of processors.
|
||||
//
|
||||
uint16_t PartitionCount;
|
||||
|
||||
//
|
||||
// Maximum batch sizes supported for send.
|
||||
//
|
||||
uint8_t MaxSendBatchSize;
|
||||
|
||||
//
|
||||
// Uses RIO interface instead of normal asyc IO.
|
||||
//
|
||||
uint8_t UseRio : 1;
|
||||
|
||||
//
|
||||
// Debug flags
|
||||
//
|
||||
uint8_t Uninitialized : 1;
|
||||
uint8_t Freed : 1;
|
||||
|
||||
uint8_t UseTcp : 1;
|
||||
|
||||
CXPLAT_DATAPATH_RAW* RawDataPath;
|
||||
|
||||
//
|
||||
// Per-processor completion contexts.
|
||||
//
|
||||
CXPLAT_DATAPATH_PARTITION Partitions[0];
|
||||
|
||||
} CXPLAT_DATAPATH;
|
||||
|
||||
//
|
||||
// Per-port state. Multiple sockets are created on each port.
|
||||
//
|
||||
typedef struct CXPLAT_SOCKET {
|
||||
CXPLAT_SOCKET_COMMON;
|
||||
|
||||
//
|
||||
// Parent datapath.
|
||||
//
|
||||
// CXPLAT_DATAPATH_BASE* Datapath;
|
||||
CXPLAT_DATAPATH* Datapath;
|
||||
|
||||
//
|
||||
// Client context pointer.
|
||||
//
|
||||
void *ClientContext;
|
||||
|
||||
//
|
||||
// Synchronization mechanism for cleanup.
|
||||
//
|
||||
CXPLAT_REF_COUNT RefCount;
|
||||
|
||||
//
|
||||
// The size of a receive buffer's payload.
|
||||
//
|
||||
uint32_t RecvBufLen;
|
||||
|
||||
//
|
||||
// The local interface's MTU.
|
||||
//
|
||||
uint16_t Mtu;
|
||||
|
||||
//
|
||||
// Indicates the binding connected to a remote IP address.
|
||||
//
|
||||
BOOLEAN Connected : 1;
|
||||
|
||||
//
|
||||
// Socket type.
|
||||
//
|
||||
uint8_t Type : 2; // CXPLAT_SOCKET_TYPE
|
||||
|
||||
//
|
||||
// Flag indicates the socket has more than one socket, affinitized to all
|
||||
// the processors.
|
||||
//
|
||||
uint16_t NumPerProcessorSockets : 1;
|
||||
|
||||
//
|
||||
// Flag indicates the socket has a default remote destination.
|
||||
//
|
||||
uint8_t HasFixedRemoteAddress : 1;
|
||||
|
||||
//
|
||||
// Flag indicates the socket indicated a disconnect event.
|
||||
//
|
||||
uint8_t DisconnectIndicated : 1;
|
||||
|
||||
//
|
||||
// Flag indicates the binding is being used for PCP.
|
||||
//
|
||||
uint8_t PcpBinding : 1;
|
||||
|
||||
//
|
||||
// Flag indicates the socket is using RIO instead of traditional Winsock.
|
||||
//
|
||||
uint8_t UseRio : 1;
|
||||
|
||||
//
|
||||
// Debug flags.
|
||||
//
|
||||
uint8_t Uninitialized : 1;
|
||||
uint8_t Freed : 1;
|
||||
|
||||
uint8_t UseTcp : 1; // Quic over TCP
|
||||
|
||||
uint8_t RawSocketAvailable : 1;
|
||||
|
||||
//
|
||||
// Per-processor socket contexts.
|
||||
//
|
||||
CXPLAT_SOCKET_PROC PerProcSockets[0];
|
||||
|
||||
} CXPLAT_SOCKET;
|
||||
|
||||
#elif defined(CX_PLATFORM_LINUX) || defined(CX_PLATFORM_DARWIN)
|
||||
|
||||
typedef struct CX_PLATFORM {
|
||||
|
@ -245,12 +664,15 @@ CxPlatDataPathPoll(
|
|||
_Out_ BOOLEAN* RemoveFromPolling
|
||||
);
|
||||
|
||||
typedef struct DATAPATH_SQE {
|
||||
uint32_t CqeType;
|
||||
#ifdef CXPLAT_SQE
|
||||
CXPLAT_SQE Sqe;
|
||||
#endif
|
||||
} DATAPATH_SQE;
|
||||
//
|
||||
// Queries the raw datapath stack for the total size needed to allocate the
|
||||
// datapath structure.
|
||||
//
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
size_t
|
||||
CxPlatDpRawGetDatapathSize(
|
||||
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
|
||||
);
|
||||
|
||||
#define CXPLAT_CQE_TYPE_WORKER_WAKE CXPLAT_CQE_TYPE_QUIC_BASE + 1
|
||||
#define CXPLAT_CQE_TYPE_WORKER_UPDATE_POLL CXPLAT_CQE_TYPE_QUIC_BASE + 2
|
||||
|
@ -259,3 +681,522 @@ typedef struct DATAPATH_SQE {
|
|||
#define CXPLAT_CQE_TYPE_SOCKET_FLUSH_TX CXPLAT_CQE_TYPE_QUIC_BASE + 5
|
||||
|
||||
extern CXPLAT_RUNDOWN_REF CxPlatWorkerRundown;
|
||||
|
||||
#if defined(CX_PLATFORM_LINUX)
|
||||
|
||||
typedef struct CXPLAT_DATAPATH_PARTITION CXPLAT_DATAPATH_PARTITION;
|
||||
|
||||
//
|
||||
// Socket context.
|
||||
//
|
||||
typedef struct QUIC_CACHEALIGN CXPLAT_SOCKET_CONTEXT {
|
||||
|
||||
//
|
||||
// The datapath binding this socket context belongs to.
|
||||
//
|
||||
CXPLAT_SOCKET* Binding;
|
||||
|
||||
//
|
||||
// The datapath proc context this socket belongs to.
|
||||
//
|
||||
CXPLAT_DATAPATH_PARTITION* DatapathPartition;
|
||||
|
||||
//
|
||||
// The socket FD used by this socket context.
|
||||
//
|
||||
int SocketFd;
|
||||
|
||||
//
|
||||
// The submission queue event for shutdown.
|
||||
//
|
||||
DATAPATH_SQE ShutdownSqe;
|
||||
|
||||
//
|
||||
// The submission queue event for IO.
|
||||
//
|
||||
DATAPATH_SQE IoSqe;
|
||||
|
||||
//
|
||||
// The submission queue event for flushing the send queue.
|
||||
//
|
||||
DATAPATH_SQE FlushTxSqe;
|
||||
|
||||
//
|
||||
// The head of list containg all pending sends on this socket.
|
||||
//
|
||||
CXPLAT_LIST_ENTRY TxQueue;
|
||||
|
||||
//
|
||||
// Lock around the PendingSendData list.
|
||||
//
|
||||
CXPLAT_LOCK TxQueueLock;
|
||||
|
||||
//
|
||||
// Rundown for synchronizing clean up with upcalls.
|
||||
//
|
||||
CXPLAT_RUNDOWN_REF UpcallRundown;
|
||||
|
||||
//
|
||||
// Inidicates the SQEs have been initialized.
|
||||
//
|
||||
BOOLEAN SqeInitialized : 1;
|
||||
|
||||
//
|
||||
// Inidicates if the socket has started IO processing.
|
||||
//
|
||||
BOOLEAN IoStarted : 1;
|
||||
|
||||
#if DEBUG
|
||||
uint8_t Uninitialized : 1;
|
||||
uint8_t Freed : 1;
|
||||
#endif
|
||||
|
||||
} CXPLAT_SOCKET_CONTEXT;
|
||||
|
||||
//
|
||||
// Datapath binding.
|
||||
//
|
||||
typedef struct CXPLAT_SOCKET {
|
||||
CXPLAT_SOCKET_COMMON;
|
||||
|
||||
//
|
||||
// A pointer to datapath object.
|
||||
//
|
||||
CXPLAT_DATAPATH* Datapath;
|
||||
|
||||
//
|
||||
// The client context for this binding.
|
||||
//
|
||||
void *ClientContext;
|
||||
|
||||
//
|
||||
// Synchronization mechanism for cleanup.
|
||||
//
|
||||
CXPLAT_REF_COUNT RefCount;
|
||||
|
||||
//
|
||||
// The MTU for this binding.
|
||||
//
|
||||
uint16_t Mtu;
|
||||
|
||||
//
|
||||
// Indicates the binding connected to a remote IP address.
|
||||
//
|
||||
BOOLEAN Connected : 1;
|
||||
|
||||
//
|
||||
// Flag indicates the socket has a default remote destination.
|
||||
//
|
||||
BOOLEAN HasFixedRemoteAddress : 1;
|
||||
|
||||
//
|
||||
// Flag indicates the binding is being used for PCP.
|
||||
//
|
||||
BOOLEAN PcpBinding : 1;
|
||||
|
||||
#if DEBUG
|
||||
uint8_t Uninitialized : 1;
|
||||
uint8_t Freed : 1;
|
||||
#endif
|
||||
|
||||
uint8_t UseTcp : 1; // Quic over TCP
|
||||
|
||||
//
|
||||
// Set of socket contexts one per proc.
|
||||
//
|
||||
CXPLAT_SOCKET_CONTEXT SocketContexts[];
|
||||
|
||||
} CXPLAT_SOCKET;
|
||||
|
||||
//
|
||||
// A per processor datapath context.
|
||||
//
|
||||
typedef struct QUIC_CACHEALIGN CXPLAT_DATAPATH_PARTITION {
|
||||
|
||||
//
|
||||
// A pointer to the datapath.
|
||||
//
|
||||
CXPLAT_DATAPATH* Datapath;
|
||||
|
||||
//
|
||||
// The event queue for this proc context.
|
||||
//
|
||||
CXPLAT_EVENTQ* EventQ;
|
||||
|
||||
//
|
||||
// Synchronization mechanism for cleanup.
|
||||
//
|
||||
CXPLAT_REF_COUNT RefCount;
|
||||
|
||||
//
|
||||
// The ideal processor of the context.
|
||||
//
|
||||
uint16_t PartitionIndex;
|
||||
|
||||
#if DEBUG
|
||||
uint8_t Uninitialized : 1;
|
||||
#endif
|
||||
|
||||
//
|
||||
// Pool of receive packet contexts and buffers to be shared by all sockets
|
||||
// on this core.
|
||||
//
|
||||
CXPLAT_POOL RecvBlockPool;
|
||||
|
||||
//
|
||||
// Pool of send packet contexts and buffers to be shared by all sockets
|
||||
// on this core.
|
||||
//
|
||||
CXPLAT_POOL SendBlockPool;
|
||||
|
||||
} CXPLAT_DATAPATH_PARTITION;
|
||||
|
||||
//
|
||||
// Represents a datapath object.
|
||||
//
|
||||
|
||||
typedef struct CXPLAT_DATAPATH {
|
||||
CXPLAT_DATAPATH_COMMON;
|
||||
|
||||
//
|
||||
// Synchronization mechanism for cleanup.
|
||||
//
|
||||
CXPLAT_REF_COUNT RefCount;
|
||||
|
||||
//
|
||||
// Set of supported features.
|
||||
//
|
||||
uint32_t Features;
|
||||
|
||||
//
|
||||
// The proc count to create per proc datapath state.
|
||||
//
|
||||
uint32_t PartitionCount;
|
||||
|
||||
//
|
||||
// The length of the CXPLAT_SEND_DATA. Calculated based on the support level
|
||||
// for GSO. No GSO support requires a larger send data to hold the extra
|
||||
// iovec structs.
|
||||
//
|
||||
uint32_t SendDataSize;
|
||||
|
||||
//
|
||||
// When not using GSO, we preallocate multiple iovec structs to use with
|
||||
// sendmmsg (to simulate GSO).
|
||||
//
|
||||
uint32_t SendIoVecCount;
|
||||
|
||||
//
|
||||
// The length of the CXPLAT_RECV_DATA and client data part of the
|
||||
// DATAPATH_RX_IO_BLOCK.
|
||||
//
|
||||
uint32_t RecvBlockStride;
|
||||
|
||||
//
|
||||
// The offset of the raw buffer in the DATAPATH_RX_IO_BLOCK.
|
||||
//
|
||||
uint32_t RecvBlockBufferOffset;
|
||||
|
||||
//
|
||||
// The total length of the DATAPATH_RX_IO_BLOCK. Calculated based on the
|
||||
// support level for GRO. No GRO only uses a single CXPLAT_RECV_DATA and
|
||||
// client data, while GRO allows for multiple.
|
||||
//
|
||||
uint32_t RecvBlockSize;
|
||||
|
||||
#if DEBUG
|
||||
uint8_t Uninitialized : 1;
|
||||
uint8_t Freed : 1;
|
||||
#endif
|
||||
|
||||
//
|
||||
// The per proc datapath contexts.
|
||||
//
|
||||
CXPLAT_DATAPATH_PARTITION Partitions[];
|
||||
|
||||
} CXPLAT_DATAPATH;
|
||||
|
||||
#endif // CX_PLATFORM_LINUX
|
||||
|
||||
#if defined(CX_PLATFORM_LINUX) || _WIN32
|
||||
|
||||
typedef struct CXPLAT_SOCKET_RAW CXPLAT_SOCKET_RAW;
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
SocketCreateUdp(
|
||||
_In_ CXPLAT_DATAPATH* DataPath,
|
||||
_In_ const CXPLAT_UDP_CONFIG* Config,
|
||||
_Out_ CXPLAT_SOCKET** NewSocket
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
SocketCreateTcp(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_opt_ const QUIC_ADDR* LocalAddress,
|
||||
_In_ const QUIC_ADDR* RemoteAddress,
|
||||
_In_opt_ void* CallbackContext,
|
||||
_Out_ CXPLAT_SOCKET** Socket
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
SocketCreateTcpListener(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_opt_ const QUIC_ADDR* LocalAddress,
|
||||
_In_opt_ void* RecvCallbackContext,
|
||||
_Out_ CXPLAT_SOCKET** NewSocket
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
SocketDelete(
|
||||
_In_ CXPLAT_SOCKET* Socket
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
DataPathInitialize(
|
||||
_In_ uint32_t ClientRecvDataLength,
|
||||
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
|
||||
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
|
||||
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
|
||||
_Out_ CXPLAT_DATAPATH** NewDatapath
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
DataPathUninitialize(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
DataPathUpdateConfig(
|
||||
_In_ CXPLAT_DATAPATH* Datapath,
|
||||
_In_ QUIC_EXECUTION_CONFIG* Config
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
uint32_t
|
||||
DataPathGetSupportedFeatures(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
DataPathIsPaddingPreferred(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
RecvDataReturn(
|
||||
_In_ CXPLAT_RECV_DATA* RecvDataChain
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
CXPLAT_SEND_DATA*
|
||||
SendDataAlloc(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_Inout_ CXPLAT_SEND_CONFIG* Config
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
SendDataFree(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
QUIC_BUFFER*
|
||||
SendDataAllocBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ uint16_t MaxBufferLength
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
SendDataFreeBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ QUIC_BUFFER* Buffer
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
SendDataIsFull(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
QUIC_STATUS
|
||||
SocketSend(
|
||||
_In_ CXPLAT_SOCKET* Socket,
|
||||
_In_ const CXPLAT_ROUTE* Route,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
);
|
||||
|
||||
void
|
||||
DataPathProcessCqe(
|
||||
_In_ CXPLAT_CQE* Cqe
|
||||
);
|
||||
|
||||
CXPLAT_SOCKET*
|
||||
CxPlatRawToSocket(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
);
|
||||
|
||||
CXPLAT_SOCKET_RAW*
|
||||
CxPlatSocketToRaw(
|
||||
_In_ CXPLAT_SOCKET* Socketh
|
||||
);
|
||||
|
||||
uint32_t
|
||||
CxPlatGetRawSocketSize(void);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
RawSocketCreateUdp(
|
||||
_In_ CXPLAT_DATAPATH_RAW* DataPath,
|
||||
_In_ const CXPLAT_UDP_CONFIG* Config,
|
||||
_Inout_ CXPLAT_SOCKET_RAW* NewSocket
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
RawSocketDelete(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
RawDataPathInitialize(
|
||||
_In_ uint32_t ClientRecvContextLength,
|
||||
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
|
||||
_In_opt_ const CXPLAT_DATAPATH* ParentDataPath,
|
||||
_Out_ CXPLAT_DATAPATH_RAW** DataPath
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
RawDataPathUninitialize(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
RawDataPathUpdateConfig(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath,
|
||||
_In_ QUIC_EXECUTION_CONFIG* Config
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
uint32_t
|
||||
RawDataPathGetSupportedFeatures(
|
||||
_In_ CXPLAT_DATAPATH_RAW* Datapath
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
RawDataPathIsPaddingPreferred(
|
||||
_In_ CXPLAT_DATAPATH* Datapath
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
RawSocketUpdateQeo(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_reads_(OffloadCount)
|
||||
const CXPLAT_QEO_CONNECTION* Offloads,
|
||||
_In_ uint32_t OffloadCount
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
uint16_t
|
||||
RawSocketGetLocalMtu(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
RawRecvDataReturn(
|
||||
_In_ CXPLAT_RECV_DATA* RecvDataChain
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
CXPLAT_SEND_DATA*
|
||||
RawSendDataAlloc(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_Inout_ CXPLAT_SEND_CONFIG* Config
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
RawSendDataFree(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
_Success_(return != NULL)
|
||||
QUIC_BUFFER*
|
||||
RawSendDataAllocBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ uint16_t MaxBufferLength
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void
|
||||
RawSendDataFreeBuffer(
|
||||
_In_ CXPLAT_SEND_DATA* SendData,
|
||||
_In_ QUIC_BUFFER* Buffer
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
BOOLEAN
|
||||
RawSendDataIsFull(
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
QUIC_STATUS
|
||||
RawSocketSend(
|
||||
_In_ CXPLAT_SOCKET_RAW* Socket,
|
||||
_In_ const CXPLAT_ROUTE* Route,
|
||||
_In_ CXPLAT_SEND_DATA* SendData
|
||||
);
|
||||
|
||||
void
|
||||
RawResolveRouteComplete(
|
||||
_In_ void* Context,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_reads_bytes_(6) const uint8_t* PhysicalAddress,
|
||||
_In_ uint8_t PathId
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
QUIC_STATUS
|
||||
RawResolveRoute(
|
||||
_In_ CXPLAT_SOCKET_RAW* Sock,
|
||||
_Inout_ CXPLAT_ROUTE* Route,
|
||||
_In_ uint8_t PathId,
|
||||
_In_ void* Context,
|
||||
_In_ CXPLAT_ROUTE_RESOLUTION_CALLBACK_HANDLER Callback
|
||||
);
|
||||
|
||||
void
|
||||
RawDataPathProcessCqe(
|
||||
_In_ CXPLAT_CQE* Cqe
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||
void
|
||||
RawUpdateRoute(
|
||||
_Inout_ CXPLAT_ROUTE* DstRoute,
|
||||
_In_ CXPLAT_ROUTE* SrcRoute
|
||||
);
|
||||
|
||||
#endif // CX_PLATFORM_LINUX || _WIN32
|
|
@ -843,6 +843,9 @@ TEST_P(WithFamilyArgs, InterfaceBinding) {
|
|||
if (TestingKernelMode) {
|
||||
ASSERT_TRUE(DriverClient.Run(IOCTL_QUIC_RUN_INTERFACE_BINDING, GetParam().Family));
|
||||
} else {
|
||||
if (UseDuoNic) {
|
||||
GTEST_SKIP_("DuoNIC is not supported");
|
||||
}
|
||||
QuicTestInterfaceBinding(GetParam().Family);
|
||||
}
|
||||
}
|
||||
|
@ -1551,6 +1554,11 @@ TEST_P(WithFamilyArgs, RebindAddr) {
|
|||
};
|
||||
ASSERT_TRUE(DriverClient.Run(IOCTL_QUIC_RUN_NAT_ADDR_REBIND, Params));
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
if (!UseDuoNic) {
|
||||
GTEST_SKIP_("Raw socket with 127.0.0.2/::2 is not supported");
|
||||
}
|
||||
#endif
|
||||
QuicTestNatAddrRebind(GetParam().Family, 0);
|
||||
}
|
||||
}
|
||||
|
@ -1572,6 +1580,11 @@ TEST_P(WithRebindPaddingArgs, RebindAddrPadded) {
|
|||
};
|
||||
ASSERT_TRUE(DriverClient.Run(IOCTL_QUIC_RUN_NAT_PORT_REBIND, Params));
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
if (!UseDuoNic) {
|
||||
GTEST_SKIP_("Raw socket with 127.0.0.2/::2 is not supported");
|
||||
}
|
||||
#endif
|
||||
QuicTestNatAddrRebind(GetParam().Family, GetParam().Padding);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче