* 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:
Daiki AMINAKA 2023-09-23 12:45:17 -07:00 коммит произвёл GitHub
Родитель f9d26ac7c0
Коммит ae3db5cd99
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
63 изменённых файлов: 3172 добавлений и 2870 удалений

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

@ -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

10
.github/workflows/build-reuse-win.yml поставляемый
Просмотреть файл

@ -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

21
.github/workflows/build.yml поставляемый
Просмотреть файл

@ -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

2
.github/workflows/cargo.yml поставляемый
Просмотреть файл

@ -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

9
.github/workflows/code-coverage.yml поставляемый
Просмотреть файл

@ -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

8
.github/workflows/stress.yml поставляемый
Просмотреть файл

@ -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'

10
.github/workflows/test.yml поставляемый
Просмотреть файл

@ -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

Двоичный файл не отображается.

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

@ -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,

800
src/platform/datapath_win.c Normal file
Просмотреть файл

@ -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);
}
}